summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk14
-rw-r--r--api/current.txt125
-rw-r--r--api/removed.txt4
-rw-r--r--api/system-current.txt163
-rw-r--r--api/system-removed.txt4
-rw-r--r--api/test-current.txt129
-rw-r--r--api/test-removed.txt4
-rw-r--r--core/java/android/app/Activity.java21
-rw-r--r--core/java/android/app/ActivityManager.java7
-rw-r--r--core/java/android/app/ActivityOptions.java2
-rw-r--r--core/java/android/app/ActivityThread.java60
-rw-r--r--core/java/android/app/ApplicationLoaders.java33
-rw-r--r--core/java/android/app/ApplicationPackageManager.java9
-rw-r--r--core/java/android/app/ContextImpl.java27
-rw-r--r--core/java/android/app/DialogFragment.java4
-rw-r--r--core/java/android/app/Fragment.java14
-rw-r--r--core/java/android/app/FragmentManager.java56
-rw-r--r--core/java/android/app/IActivityManager.aidl7
-rw-r--r--core/java/android/app/Notification.java1
-rw-r--r--core/java/android/app/NotificationManager.java3
-rw-r--r--core/java/android/app/PendingIntent.java38
-rw-r--r--core/java/android/app/SystemServiceRegistry.java12
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java45
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java1
-rw-r--r--core/java/android/bluetooth/BluetoothCodecConfig.java22
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java6
-rw-r--r--core/java/android/bluetooth/BluetoothGattServer.java6
-rw-r--r--core/java/android/bluetooth/IBluetoothA2dp.aidl2
-rw-r--r--core/java/android/bluetooth/IBluetoothGatt.aidl8
-rw-r--r--core/java/android/bluetooth/IBluetoothGattCallback.aidl (renamed from core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl)2
-rw-r--r--core/java/android/bluetooth/IBluetoothGattServerCallback.aidl (renamed from core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl)2
-rw-r--r--core/java/android/bluetooth/le/AdvertisingSetParameters.java24
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java1
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingManager.java1
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java2
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingReport.java1
-rw-r--r--core/java/android/companion/AssociationRequest.java15
-rw-r--r--core/java/android/companion/BluetoothDeviceFilter.java17
-rw-r--r--core/java/android/companion/BluetoothDeviceFilterUtils.java6
-rw-r--r--core/java/android/companion/BluetoothLEDeviceFilter.java78
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java12
-rw-r--r--core/java/android/companion/WifiDeviceFilter.java14
-rw-r--r--core/java/android/content/ClipboardManager.java4
-rw-r--r--core/java/android/content/ContentProviderOperation.java8
-rw-r--r--core/java/android/content/ContentValues.java11
-rw-r--r--core/java/android/content/Context.java44
-rw-r--r--core/java/android/content/ContextWrapper.java13
-rw-r--r--core/java/android/content/Intent.java13
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageManager.java16
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java15
-rw-r--r--core/java/android/content/pm/PackageParser.java8
-rw-r--r--core/java/android/content/pm/ShortcutManager.java1
-rw-r--r--core/java/android/database/PageViewCursor.java102
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java4
-rw-r--r--core/java/android/hardware/camera2/CameraCaptureSession.java5
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java10
-rw-r--r--core/java/android/hardware/camera2/params/StreamConfigurationMap.java7
-rw-r--r--core/java/android/hardware/radio/RadioManager.java52
-rw-r--r--core/java/android/hardware/radio/RadioModule.java6
-rw-r--r--core/java/android/hardware/radio/RadioTuner.java72
-rw-r--r--core/java/android/metrics/LogMaker.java11
-rw-r--r--core/java/android/net/IIpSecService.aidl24
-rw-r--r--core/java/android/net/IpSecManager.java53
-rw-r--r--core/java/android/net/IpSecTransform.java4
-rw-r--r--core/java/android/net/NetworkScoreManager.java8
-rw-r--r--core/java/android/net/NetworkScorerAppData.java24
-rw-r--r--core/java/android/os/Handler.java18
-rw-r--r--core/java/android/os/HidlSupport.java159
-rw-r--r--core/java/android/os/Looper.java22
-rw-r--r--core/java/android/os/RecoverySystem.java29
-rw-r--r--core/java/android/os/ZygoteProcess.java9
-rw-r--r--core/java/android/os/storage/StorageManager.java79
-rw-r--r--core/java/android/preference/Preference.java33
-rwxr-xr-xcore/java/android/provider/Settings.java46
-rw-r--r--core/java/android/provider/VoicemailContract.java2
-rw-r--r--core/java/android/service/quicksettings/TileService.java1
-rw-r--r--core/java/android/service/resolver/IResolverRankerResult.aidl27
-rw-r--r--core/java/android/service/resolver/IResolverRankerService.aidl29
-rw-r--r--core/java/android/service/resolver/ResolverRankerService.java187
-rw-r--r--core/java/android/service/resolver/ResolverTarget.aidl22
-rw-r--r--core/java/android/service/resolver/ResolverTarget.java216
-rw-r--r--core/java/android/speech/tts/UtteranceProgressListener.java10
-rw-r--r--core/java/android/text/FontConfig.java83
-rw-r--r--core/java/android/util/ExceptionUtils.java21
-rw-r--r--core/java/android/view/ContextThemeWrapper.java4
-rw-r--r--core/java/android/view/FocusFinder.java37
-rw-r--r--core/java/android/view/SurfaceView.java25
-rw-r--r--core/java/android/view/View.java45
-rw-r--r--core/java/android/view/ViewConfiguration.java45
-rw-r--r--core/java/android/view/ViewGroup.java54
-rw-r--r--core/java/android/view/ViewRootImpl.java80
-rw-r--r--core/java/android/view/autofill/AutofillManager.java10
-rw-r--r--core/java/android/view/inputmethod/InputMethodSubtype.java34
-rw-r--r--core/java/android/view/textclassifier/SmartSelection.java11
-rw-r--r--core/java/android/view/textclassifier/TextClassificationManager.java12
-rw-r--r--core/java/android/view/textclassifier/TextClassifierImpl.java126
-rw-r--r--core/java/android/webkit/WebView.java19
-rw-r--r--core/java/android/webkit/WebViewFactory.java52
-rw-r--r--core/java/android/webkit/WebViewProvider.java9
-rw-r--r--core/java/android/webkit/WebViewZygote.java13
-rw-r--r--core/java/android/widget/AbsListView.java14
-rw-r--r--core/java/android/widget/AbsSpinner.java12
-rw-r--r--core/java/android/widget/CompoundButton.java11
-rw-r--r--core/java/android/widget/DatePicker.java11
-rw-r--r--core/java/android/widget/HorizontalScrollView.java6
-rw-r--r--core/java/android/widget/ListPopupWindow.java10
-rw-r--r--core/java/android/widget/ListView.java2
-rw-r--r--core/java/android/widget/PopupWindow.java59
-rw-r--r--core/java/android/widget/RadioGroup.java16
-rw-r--r--core/java/android/widget/ScrollView.java8
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java2
-rw-r--r--core/java/android/widget/TextView.java12
-rw-r--r--core/java/android/widget/TimePicker.java10
-rw-r--r--core/java/android/widget/Toolbar.java3
-rw-r--r--core/java/com/android/internal/app/LRResolverRankerService.java199
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java3
-rw-r--r--core/java/com/android/internal/app/ResolverComparator.java516
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java44
-rw-r--r--core/java/com/android/internal/app/ToolbarActionBar.java18
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java3
-rw-r--r--core/java/com/android/internal/os/FuseAppLoop.java303
-rw-r--r--core/java/com/android/internal/os/FuseUnavailableMountException.java (renamed from media/java/android/media/UnsupportedCasException.java)11
-rw-r--r--core/java/com/android/internal/os/WebViewZygoteInit.java11
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java6
-rw-r--r--core/java/com/android/internal/util/StateMachine.java17
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java48
-rw-r--r--core/jni/android_hardware_Radio.cpp5
-rw-r--r--core/jni/android_view_Surface.cpp10
-rw-r--r--core/jni/android_view_SurfaceControl.cpp2
-rw-r--r--core/jni/com_android_internal_os_FuseAppLoop.cpp224
-rw-r--r--core/jni/include/android_runtime/android_view_Surface.h1
-rw-r--r--core/res/AndroidManifest.xml28
-rw-r--r--core/res/res/layout/screen_action_bar.xml2
-rw-r--r--core/res/res/layout/screen_toolbar.xml1
-rw-r--r--core/res/res/values/attrs.xml4
-rw-r--r--core/res/res/values/config.xml27
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/strings.xml33
-rw-r--r--core/res/res/values/styles.xml1
-rw-r--r--core/res/res/values/symbols.xml17
-rw-r--r--core/tests/coretests/README4
-rw-r--r--core/tests/coretests/src/android/content/ContentTests.java1
-rw-r--r--core/tests/coretests/src/android/content/ContentValuesTest.java46
-rw-r--r--core/tests/coretests/src/android/database/PageViewCursorTest.java170
-rw-r--r--core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java4
-rw-r--r--core/tests/coretests/src/android/provider/SettingsProviderTest.java1
-rwxr-xr-xcore/tests/utiltests/runtests.sh24
-rw-r--r--core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java60
-rw-r--r--data/etc/platform.xml4
-rw-r--r--graphics/java/android/graphics/Color.java39
-rw-r--r--graphics/java/android/graphics/FontListParser.java5
-rw-r--r--graphics/java/android/graphics/ImageFormat.java11
-rw-r--r--graphics/java/android/graphics/Typeface.java11
-rw-r--r--libs/androidfw/LoadedArsc.cpp4
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/BakedOpRenderer.cpp1
-rw-r--r--libs/hwui/GlLayer.h2
-rw-r--r--libs/hwui/GlopBuilder.cpp6
-rw-r--r--libs/hwui/JankTracker.cpp5
-rw-r--r--libs/hwui/Program.h53
-rw-r--r--libs/hwui/ProgramCache.cpp137
-rw-r--r--libs/hwui/SkiaShader.cpp7
-rw-r--r--libs/hwui/Texture.cpp89
-rw-r--r--libs/hwui/Texture.h35
-rw-r--r--libs/hwui/VectorDrawable.cpp30
-rw-r--r--libs/hwui/VectorDrawable.h25
-rw-r--r--libs/hwui/hwui/Bitmap.cpp7
-rw-r--r--libs/hwui/hwui_static_deps.mk4
-rw-r--r--libs/hwui/pipeline/skia/SkiaDisplayList.cpp3
-rw-r--r--libs/hwui/pipeline/skia/SkiaDisplayList.h2
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.cpp31
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.h12
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp22
-rw-r--r--libs/hwui/renderstate/RenderState.cpp37
-rw-r--r--libs/hwui/renderthread/CanvasContext.h2
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp1
-rw-r--r--libs/hwui/tests/unit/SkiaBehaviorTests.cpp14
-rw-r--r--libs/hwui/utils/Color.cpp58
-rw-r--r--libs/hwui/utils/Color.h13
-rw-r--r--media/java/android/media/AudioAttributes.java21
-rw-r--r--media/java/android/media/AudioManagerInternal.java3
-rw-r--r--media/java/android/media/ImageUtils.java7
-rw-r--r--media/java/android/media/MediaCas.java123
-rw-r--r--media/java/android/media/MediaCasException.java93
-rw-r--r--media/java/android/media/MediaCasStateException.java93
-rw-r--r--media/java/android/media/MediaCodec.java13
-rw-r--r--media/java/android/media/MediaDescrambler.java41
-rw-r--r--media/java/android/media/session/MediaSession.java6
-rw-r--r--media/java/android/media/tv/TvContract.java7
-rw-r--r--media/java/android/media/tv/TvInputHardwareInfo.java30
-rw-r--r--media/jni/android_media_MediaDescrambler.cpp106
-rw-r--r--media/jni/android_media_MediaDescrambler.h7
-rw-r--r--packages/CarrierDefaultApp/AndroidManifest.xml4
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java60
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java6
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java23
-rw-r--r--packages/SettingsLib/res/values-af/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-am/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ar/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml48
-rw-r--r--packages/SettingsLib/res/values-az/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-be/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-bg/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-bn/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-bs/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ca/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-cs/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-da/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-de/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-el/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-en-rAU/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-en-rGB/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-en-rIN/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-es-rUS/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-es/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-et/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-eu/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-fa/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-fi/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-fr/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-gl/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-gu/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-hi/arrays.xml12
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-hr/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-hu/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-hy/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-in/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-is/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-it/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-iw/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ja/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ka/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-kk/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-km/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-kn/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ko/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ky/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-lo/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-lt/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-lv/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-mk/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ml/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-mn/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-mr/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ms/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-my/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-nb/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ne/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-nl/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-pa/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-pl/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-pt/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ro/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ru/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-si/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-sk/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-sl/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-sq/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-sr/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-sv/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-sw/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ta/arrays.xml12
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-te/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-th/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-tl/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-tr/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-uk/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-ur/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-uz/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-vi/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml44
-rw-r--r--packages/SettingsLib/res/values-zu/arrays.xml28
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml44
-rw-r--r--packages/SettingsLib/res/values/arrays.xml9
-rw-r--r--packages/SettingsLib/res/values/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java40
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java18
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java16
-rwxr-xr-xpackages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java10
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java14
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java38
-rw-r--r--packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml2
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java109
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java61
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java24
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/Android.mk1
-rw-r--r--packages/SystemUI/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/plugin/Android.mk2
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java4
-rw-r--r--packages/SystemUI/res/layout/qs_detail.xml4
-rw-r--r--packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml7
-rw-r--r--packages/SystemUI/res/values/strings.xml14
-rw-r--r--packages/SystemUI/res/xml/tuner_prefs.xml14
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java110
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDetail.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooter.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSHost.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java93
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java97
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java103
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java67
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java65
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java51
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java83
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java174
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java115
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java2
-rw-r--r--proto/src/metrics_constants.proto25
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java19
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java852
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java764
-rw-r--r--services/autofill/java/com/android/server/autofill/ViewState.java125
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java18
-rw-r--r--services/core/java/com/android/server/BatteryService.java5
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java41
-rw-r--r--services/core/java/com/android/server/FontManagerService.java22
-rw-r--r--services/core/java/com/android/server/IpSecService.java114
-rw-r--r--services/core/java/com/android/server/NetworkScorerAppManager.java19
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java59
-rw-r--r--services/core/java/com/android/server/UiThread.java11
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java97
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java1091
-rw-r--r--services/core/java/com/android/server/accounts/AccountsDb.java39
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java105
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java61
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java20
-rw-r--r--services/core/java/com/android/server/am/ActivityMetricsLogger.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java105
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java30
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java26
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java2
-rw-r--r--services/core/java/com/android/server/am/LockTaskNotify.java10
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java8
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java2
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java47
-rw-r--r--services/core/java/com/android/server/am/UserState.java2
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java63
-rw-r--r--services/core/java/com/android/server/connectivity/MockableSystemProperties.java13
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java128
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java7
-rw-r--r--services/core/java/com/android/server/fingerprint/EnumerateClient.java6
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java198
-rw-r--r--services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java94
-rw-r--r--services/core/java/com/android/server/fingerprint/InternalRemovalClient.java33
-rw-r--r--services/core/java/com/android/server/media/AudioPlaybackMonitor.java201
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java73
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java161
-rw-r--r--services/core/java/com/android/server/media/MediaSessionStack.java278
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java372
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java6
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerServiceImpl.java3
-rw-r--r--services/core/java/com/android/server/pm/OtaDexoptService.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java213
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java4
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java6
-rw-r--r--services/core/java/com/android/server/storage/AppFuseBridge.java44
-rw-r--r--services/core/java/com/android/server/storage/CacheQuotaStrategy.java2
-rw-r--r--services/core/java/com/android/server/tv/TvInputHal.java8
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java9
-rw-r--r--services/core/java/com/android/server/wm/AppWindowContainerController.java4
-rw-r--r--services/core/java/com/android/server/wm/AppWindowContainerListener.java6
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java18
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java34
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java5
-rw-r--r--services/core/java/com/android/server/wm/PinnedStackController.java3
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java16
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java13
-rw-r--r--services/core/jni/com_android_server_am_BatteryStatsService.cpp91
-rw-r--r--services/core/jni/com_android_server_power_PowerManagerService.cpp77
-rw-r--r--services/core/jni/com_android_server_tv_TvInputHal.cpp1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java101
-rw-r--r--services/java/com/android/server/SystemServer.java20
-rw-r--r--services/net/java/android/net/ip/IpManager.java2
-rw-r--r--services/print/java/com/android/server/print/CompanionDeviceManagerService.java77
-rw-r--r--services/tests/servicestests/Android.mk1
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java359
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java63
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java4
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsDatabase.java6
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java31
-rw-r--r--telecomm/java/android/telecom/Call.java5
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java8
-rw-r--r--telephony/java/android/telephony/SmsManager.java4
-rw-r--r--telephony/java/com/android/ims/ImsException.java2
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyIntents.java2
-rw-r--r--test-runner/src/android/test/mock/MockContext.java12
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java8
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java46
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java51
-rw-r--r--tests/testables/src/android/testing/BaseFragmentTest.java21
-rw-r--r--tools/aapt/Resource.cpp7
-rw-r--r--tools/aapt/ResourceTable.cpp82
-rw-r--r--tools/aapt/ResourceTable.h7
-rw-r--r--tools/aapt2/Main.cpp2
-rw-r--r--tools/aapt2/ResourceTable.cpp164
-rw-r--r--tools/aapt2/ResourceTable.h18
-rw-r--r--tools/aapt2/ResourceTable_test.cpp10
-rw-r--r--tools/aapt2/readme.md8
-rw-r--r--tools/aapt2/unflatten/BinaryResourceParser.cpp15
-rw-r--r--tools/layoutlib/.gitignore1
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java8
-rw-r--r--tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java11
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/BlendComposite.java21
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java3
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java14
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java7
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java6
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java3
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java12
-rw-r--r--tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java4
-rw-r--r--tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java3
-rw-r--r--tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java27
-rw-r--r--tools/layoutlib/bridge/src/android/view/RectShadowPainter.java3
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java147
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java138
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java57
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java9
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java53
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java18
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java3
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java4
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java37
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java4
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java14
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java4
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java10
-rw-r--r--wifi/java/android/net/wifi/WifiEnterpriseConfig.java10
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java18
-rw-r--r--wifi/java/android/net/wifi/WifiScanner.java113
-rw-r--r--wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java2
-rw-r--r--wifi/java/android/net/wifi/aware/PublishConfig.java47
-rw-r--r--wifi/java/android/net/wifi/aware/SubscribeConfig.java44
-rw-r--r--wifi/tests/src/android/net/wifi/WifiScannerTest.java40
-rw-r--r--wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java97
586 files changed, 13872 insertions, 8390 deletions
diff --git a/Android.mk b/Android.mk
index 749242d78bd2..08ef6f59fe7b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -140,8 +140,8 @@ LOCAL_SRC_FILES += \
core/java/android/bluetooth/IBluetoothInputHost.aidl \
core/java/android/bluetooth/IBluetoothHidDeviceCallback.aidl \
core/java/android/bluetooth/IBluetoothGatt.aidl \
- core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl \
- core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl \
+ core/java/android/bluetooth/IBluetoothGattCallback.aidl \
+ core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl \
core/java/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl \
@@ -223,6 +223,7 @@ LOCAL_SRC_FILES += \
core/java/android/net/IEthernetManager.aidl \
core/java/android/net/IEthernetServiceListener.aidl \
core/java/android/net/INetdEventCallback.aidl \
+ core/java/android/net/IIpSecService.aidl \
core/java/android/net/INetworkManagementEventObserver.aidl \
core/java/android/net/INetworkPolicyListener.aidl \
core/java/android/net/INetworkPolicyManager.aidl \
@@ -319,6 +320,8 @@ LOCAL_SRC_FILES += \
core/java/android/service/wallpaper/IWallpaperService.aidl \
core/java/android/service/chooser/IChooserTargetService.aidl \
core/java/android/service/chooser/IChooserTargetResult.aidl \
+ core/java/android/service/resolver/IResolverRankerService.aidl \
+ core/java/android/service/resolver/IResolverRankerResult.aidl \
core/java/android/text/ITextClassificationService.aidl \
core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl\
core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\
@@ -567,8 +570,9 @@ LOCAL_JAVA_LIBRARIES := core-oj core-libart conscrypt okhttp bouncycastle ext
LOCAL_STATIC_JAVA_LIBRARIES := \
framework-protos \
- android.hardware.thermal@1.0-java-constants \
android.hardware.health@1.0-java-constants \
+ android.hardware.thermal@1.0-java-constants \
+ android.hardware.tv.input@1.0-java-constants \
android.hardware.usb@1.0-java-constants \
android.hardware.vibrator@1.0-java-constants \
@@ -727,6 +731,7 @@ aidl_files := \
frameworks/base/core/java/android/service/notification/SnoozeCriterion.aidl \
frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
frameworks/base/core/java/android/service/chooser/ChooserTarget.aidl \
+ frameworks/base/core/java/android/service/resolver/ResolverTarget.aidl \
frameworks/base/core/java/android/speech/tts/Voice.aidl \
frameworks/base/core/java/android/app/usage/CacheQuotaHint.aidl \
frameworks/base/core/java/android/app/usage/ExternalStorageStats.aidl \
@@ -1459,7 +1464,8 @@ LOCAL_PROTOC_FLAGS := \
LOCAL_SRC_FILES := \
$(call all-proto-files-under, core/proto) \
$(call all-proto-files-under, libs/incident/proto)
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_SHARED_LIBRARIES := libprotobuf-cpp-full
+include $(BUILD_SHARED_LIBRARY)
# ==== c++ proto host library ==============================
include $(CLEAR_VARS)
diff --git a/api/current.txt b/api/current.txt
index 8f969c1efb02..f4db2817c0a3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -696,6 +696,7 @@ package android {
field public static final int hyphenationFrequency = 16843998; // 0x10104de
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
+ field public static final int iconSpaceReserved = 16844132; // 0x1010564
field public static final int iconTint = 16844129; // 0x1010561
field public static final int iconTintMode = 16844130; // 0x1010562
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
@@ -3673,7 +3674,7 @@ package android.app {
method public void onLowMemory();
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
- method public void onMovedToDisplay(int);
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
method public void onMultiWindowModeChanged(boolean);
method public boolean onNavigateUp();
method public boolean onNavigateUpFromChild(android.app.Activity);
@@ -4609,6 +4610,7 @@ package android.app {
method public void onDestroyOptionsMenu();
method public void onDestroyView();
method public void onDetach();
+ method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle);
method public void onHiddenChanged(boolean);
method public deprecated void onInflate(android.util.AttributeSet, android.os.Bundle);
method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
@@ -4763,6 +4765,7 @@ package android.app {
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract java.util.Collection<android.app.Fragment> getFragments();
method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
@@ -5583,7 +5586,7 @@ package android.app {
method public boolean removeAutomaticZenRule(java.lang.String);
method public final void setInterruptionFilter(int);
method public void setNotificationPolicy(android.app.NotificationManager.Policy);
- method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+ method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5638,6 +5641,7 @@ package android.app {
method public java.lang.String getCreatorPackage();
method public int getCreatorUid();
method public android.os.UserHandle getCreatorUserHandle();
+ method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
method public deprecated java.lang.String getTargetPackage();
@@ -7138,7 +7142,6 @@ package android.bluetooth {
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
- method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String);
@@ -8027,21 +8030,6 @@ package android.bluetooth.le {
method public void stopScan(android.bluetooth.le.ScanCallback);
}
- public abstract class PeriodicAdvertisingCallback {
- ctor public PeriodicAdvertisingCallback();
- method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport);
- method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int);
- method public void onSyncLost(int);
- field public static final int SYNC_NO_RESOURCES = 2; // 0x2
- field public static final int SYNC_NO_RESPONSE = 1; // 0x1
- }
-
- public final class PeriodicAdvertisingManager {
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback);
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler);
- method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
- }
-
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
method public int describeContents();
method public boolean getEnable();
@@ -8059,21 +8047,6 @@ package android.bluetooth.le {
method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
}
- public final class PeriodicAdvertisingReport implements android.os.Parcelable {
- ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
- method public int describeContents();
- method public android.bluetooth.le.ScanRecord getData();
- method public int getDataStatus();
- method public int getRssi();
- method public int getSyncHandle();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2
- }
-
public abstract class ScanCallback {
ctor public ScanCallback();
method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
@@ -8855,6 +8828,7 @@ package android.content {
method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
method public abstract void startActivity(android.content.Intent);
method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+ method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9046,6 +9020,7 @@ package android.content {
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -12695,7 +12670,7 @@ package android.graphics {
enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP;
}
- public class Color {
+ public final class Color {
ctor public Color();
method public static int HSVToColor(float[]);
method public static int HSVToColor(int, float[]);
@@ -12720,6 +12695,7 @@ package android.graphics {
method public float getComponent(int);
method public int getComponentCount();
method public float[] getComponents();
+ method public float[] getComponents(float[]);
method public android.graphics.ColorSpace.Model getModel();
method public float green();
method public static float green(long);
@@ -20889,7 +20865,8 @@ package android.media {
method public int getContentType();
method public int getFlags();
method public int getUsage();
- method public static int getVolumeControlStream(android.media.AudioAttributes);
+ method public static deprecated int getVolumeControlStream(android.media.AudioAttributes);
+ method public int getVolumeControlStream();
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -21818,23 +21795,23 @@ package android.media {
}
public final class MediaCas {
- ctor public MediaCas(int) throws android.media.UnsupportedCasException;
+ ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
method public void closeSession(byte[]);
method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
method public static boolean isSystemIdSupported(int);
- method public byte[] openSession(int);
- method public byte[] openSession(int, int);
- method public void processEcm(byte[], byte[], int, int);
- method public void processEcm(byte[], byte[]);
- method public void processEmm(byte[], int, int);
- method public void processEmm(byte[]);
- method public void provision(java.lang.String);
- method public void refreshEntitlements(int, byte[]);
+ method public byte[] openSession(int) throws android.media.MediaCasException;
+ method public byte[] openSession(int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
+ method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
+ method public void processEmm(byte[]) throws android.media.MediaCasException;
+ method public void provision(java.lang.String) throws android.media.MediaCasException;
+ method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
method public void release();
- method public void sendEvent(int, int, byte[]);
+ method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
- method public void setPrivateData(byte[]);
- method public void setSessionPrivateData(byte[], byte[]);
+ method public void setPrivateData(byte[]) throws android.media.MediaCasException;
+ method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
}
public static abstract interface MediaCas.EventListener {
@@ -21847,7 +21824,22 @@ package android.media {
}
public class MediaCasException extends java.lang.Exception {
- ctor public MediaCasException(java.lang.String);
+ }
+
+ public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.ResourceBusyException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.UnsupportedCasException extends android.media.MediaCasException {
+ }
+
+ public class MediaCasStateException extends java.lang.IllegalStateException {
+ method public java.lang.String getDiagnosticInfo();
}
public final class MediaCodec {
@@ -22275,7 +22267,7 @@ package android.media {
}
public final class MediaDescrambler {
- ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException;
+ ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
method public final void release();
method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -23586,10 +23578,6 @@ package android.media {
field public static final int TONE_SUP_RINGTONE = 23; // 0x17
}
- public final class UnsupportedCasException extends android.media.MediaCasException {
- ctor public UnsupportedCasException(java.lang.String);
- }
-
public final class UnsupportedSchemeException extends android.media.MediaDrmException {
ctor public UnsupportedSchemeException(java.lang.String);
}
@@ -24326,9 +24314,9 @@ package android.media.session {
method public void setRepeatMode(int);
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
- field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
- field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+ field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSession.Callback {
@@ -24548,6 +24536,7 @@ package android.media.tv {
field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+ field public static final java.lang.String COLUMN_TRANSIENT = "transient";
field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
@@ -24625,6 +24614,7 @@ package android.media.tv {
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+ field public static final java.lang.String COLUMN_TRANSIENT = "transient";
field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
@@ -25408,7 +25398,7 @@ package android.net {
method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+ method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
}
@@ -26659,7 +26649,6 @@ package android.net.wifi.aware {
ctor public PublishConfig.Builder();
method public android.net.wifi.aware.PublishConfig build();
method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(java.util.List<byte[]>);
- method public android.net.wifi.aware.PublishConfig.Builder setPublishCount(int);
method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
method public android.net.wifi.aware.PublishConfig.Builder setServiceName(java.lang.String);
method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(byte[]);
@@ -26688,7 +26677,6 @@ package android.net.wifi.aware {
method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String);
method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]);
- method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeCount(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
@@ -31884,6 +31872,7 @@ package android.os.storage {
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback) throws java.io.IOException;
+ method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler) throws java.io.IOException;
method public void setCacheBehaviorGroup(java.io.File, boolean) throws java.io.IOException;
method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
@@ -32032,6 +32021,7 @@ package android.preference {
method public int getWidgetLayoutResource();
method public boolean hasKey();
method public boolean isEnabled();
+ method public boolean isIconSpaceReserved();
method public boolean isPersistent();
method public boolean isRecycleEnabled();
method public boolean isSelectable();
@@ -32066,6 +32056,7 @@ package android.preference {
method public void setFragment(java.lang.String);
method public void setIcon(android.graphics.drawable.Drawable);
method public void setIcon(int);
+ method public void setIconSpaceReserved(boolean);
method public void setIntent(android.content.Intent);
method public void setKey(java.lang.String);
method public void setLayoutResource(int);
@@ -34858,7 +34849,7 @@ package android.provider {
field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
- field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
+ field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay";
field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
field public static final java.lang.String WIFI_ON = "wifi_on";
@@ -37842,6 +37833,7 @@ package android.speech.tts {
method public void onRangeStart(java.lang.String, int, int, int);
method public abstract void onStart(java.lang.String);
method public void onStop(java.lang.String, boolean);
+ method public deprecated void onUtteranceRangeStart(java.lang.String, int, int);
}
public class Voice implements android.os.Parcelable {
@@ -39363,6 +39355,7 @@ package android.telephony {
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -40659,6 +40652,7 @@ package android.test.mock {
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -41062,9 +41056,9 @@ package android.text {
public static final class FontConfig.Font implements android.os.Parcelable {
method public int describeContents();
method public android.text.FontConfig.Axis[] getAxes();
- method public android.os.ParcelFileDescriptor getFd();
method public java.lang.String getFontName();
method public int getTtcIndex();
+ method public android.net.Uri getUri();
method public int getWeight();
method public boolean isItalic();
method public void writeToParcel(android.os.Parcel, int);
@@ -45141,8 +45135,8 @@ package android.view {
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
- method public boolean autofill(android.view.autofill.AutofillValue);
- method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+ method public void autofill(android.view.autofill.AutofillValue);
+ method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -45476,7 +45470,7 @@ package android.view {
method public boolean onKeyUp(int, android.view.KeyEvent);
method protected void onLayout(boolean, int, int, int, int);
method protected void onMeasure(int, int);
- method public void onMovedToDisplay(int);
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
method protected void onOverScrolled(int, int, boolean, boolean);
method public void onPointerCaptureChange(boolean);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -45977,6 +45971,7 @@ package android.view {
method public static deprecated int getEdgeSlop();
method public static deprecated int getFadingEdgeLength();
method public static deprecated long getGlobalActionKeyTimeout();
+ method public float getScaledHorizontalScrollFactor();
method public static int getJumpTapTimeout();
method public static int getKeyRepeatDelay();
method public static int getKeyRepeatTimeout();
@@ -45995,7 +45990,6 @@ package android.view {
method public int getScaledOverscrollDistance();
method public int getScaledPagingTouchSlop();
method public int getScaledScrollBarSize();
- method public int getScaledScrollFactor();
method public int getScaledTouchSlop();
method public int getScaledWindowTouchSlop();
method public static int getScrollBarFadeDuration();
@@ -46004,6 +45998,7 @@ package android.view {
method public static float getScrollFriction();
method public static int getTapTimeout();
method public static deprecated int getTouchSlop();
+ method public float getScaledVerticalScrollFactor();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
method public boolean hasPermanentMenuKey();
@@ -48811,6 +48806,7 @@ package android.webkit {
method public int getRendererRequestedPriority();
method public deprecated float getScale();
method public android.webkit.WebSettings getSettings();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
method public java.lang.String getTitle();
method public java.lang.String getUrl();
method public android.webkit.WebChromeClient getWebChromeClient();
@@ -48857,6 +48853,7 @@ package android.webkit {
method public void setNetworkAvailable(boolean);
method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
method public void setRendererPriorityPolicy(int, boolean);
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
method public deprecated void setVerticalScrollbarOverlay(boolean);
method public void setWebChromeClient(android.webkit.WebChromeClient);
method public static void setWebContentsDebuggingEnabled(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index 75da976d1b64..fa62e056757c 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -374,6 +374,10 @@ package android.view {
method protected void initializeScrollbars(android.content.res.TypedArray);
}
+ public class ViewConfiguration {
+ method public int getScaledScrollFactor();
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 48b878ec699f..fd2140b1c32e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -53,6 +53,7 @@ package android {
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
@@ -93,6 +94,7 @@ package android {
field public static final java.lang.String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
field public static final java.lang.String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
+ field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
field public static final java.lang.String CONTROL_VPN = "android.permission.CONTROL_VPN";
@@ -809,6 +811,7 @@ package android {
field public static final int hyphenationFrequency = 16843998; // 0x10104de
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
+ field public static final int iconSpaceReserved = 16844132; // 0x1010564
field public static final int iconTint = 16844129; // 0x1010561
field public static final int iconTintMode = 16844130; // 0x1010562
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
@@ -3798,7 +3801,7 @@ package android.app {
method public void onLowMemory();
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
- method public void onMovedToDisplay(int);
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
method public void onMultiWindowModeChanged(boolean);
method public boolean onNavigateUp();
method public boolean onNavigateUpFromChild(android.app.Activity);
@@ -4767,6 +4770,7 @@ package android.app {
method public void onDestroyOptionsMenu();
method public void onDestroyView();
method public void onDetach();
+ method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle);
method public void onHiddenChanged(boolean);
method public deprecated void onInflate(android.util.AttributeSet, android.os.Bundle);
method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
@@ -4921,6 +4925,7 @@ package android.app {
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract java.util.Collection<android.app.Fragment> getFragments();
method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
@@ -5308,6 +5313,7 @@ package android.app {
field public static final int DEFAULT_LIGHTS = 4; // 0x4
field public static final int DEFAULT_SOUND = 1; // 0x1
field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
field public static final java.lang.String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
@@ -5775,7 +5781,7 @@ package android.app {
method public boolean removeAutomaticZenRule(java.lang.String);
method public final void setInterruptionFilter(int);
method public void setNotificationPolicy(android.app.NotificationManager.Policy);
- method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+ method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5830,6 +5836,7 @@ package android.app {
method public java.lang.String getCreatorPackage();
method public int getCreatorUid();
method public android.os.UserHandle getCreatorUserHandle();
+ method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
method public deprecated java.lang.String getTargetPackage();
@@ -7596,7 +7603,6 @@ package android.bluetooth {
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
- method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String);
@@ -8494,21 +8500,6 @@ package android.bluetooth.le {
method public void stopScan(android.bluetooth.le.ScanCallback);
}
- public abstract class PeriodicAdvertisingCallback {
- ctor public PeriodicAdvertisingCallback();
- method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport);
- method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int);
- method public void onSyncLost(int);
- field public static final int SYNC_NO_RESOURCES = 2; // 0x2
- field public static final int SYNC_NO_RESPONSE = 1; // 0x1
- }
-
- public final class PeriodicAdvertisingManager {
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback);
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler);
- method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
- }
-
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
method public int describeContents();
method public boolean getEnable();
@@ -8526,21 +8517,6 @@ package android.bluetooth.le {
method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
}
- public final class PeriodicAdvertisingReport implements android.os.Parcelable {
- ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
- method public int describeContents();
- method public android.bluetooth.le.ScanRecord getData();
- method public int getDataStatus();
- method public int getRssi();
- method public int getSyncHandle();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2
- }
-
public final class ResultStorageDescriptor implements android.os.Parcelable {
ctor public ResultStorageDescriptor(int, int, int);
method public int describeContents();
@@ -9348,6 +9324,7 @@ package android.content {
method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
method public abstract void startActivity(android.content.Intent);
method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+ method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9553,6 +9530,7 @@ package android.content {
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -11171,6 +11149,7 @@ package android.content.pm {
method public abstract byte[] getInstantAppCookie();
method public abstract int getInstantAppCookieMaxSize();
method public abstract android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String);
+ method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent();
method public abstract java.util.List<android.content.pm.InstantAppInfo> getInstantApps();
method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
@@ -11420,6 +11399,7 @@ package android.content.pm {
field public static final int MATCH_DIRECT_BOOT_UNAWARE = 262144; // 0x40000
field public static final int MATCH_DISABLED_COMPONENTS = 512; // 0x200
field public static final int MATCH_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
+ field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
field public static final int MATCH_INSTANT = 8388608; // 0x800000
field public static final int MATCH_SYSTEM_ONLY = 1048576; // 0x100000
field public static final int MATCH_UNINSTALLED_PACKAGES = 8192; // 0x2000
@@ -13420,7 +13400,7 @@ package android.graphics {
enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP;
}
- public class Color {
+ public final class Color {
ctor public Color();
method public static int HSVToColor(float[]);
method public static int HSVToColor(int, float[]);
@@ -13445,6 +13425,7 @@ package android.graphics {
method public float getComponent(int);
method public int getComponentCount();
method public float[] getComponents();
+ method public float[] getComponents(float[]);
method public android.graphics.ColorSpace.Model getModel();
method public float green();
method public static float green(long);
@@ -22622,7 +22603,8 @@ package android.media {
method public int getContentType();
method public int getFlags();
method public int getUsage();
- method public static int getVolumeControlStream(android.media.AudioAttributes);
+ method public static deprecated int getVolumeControlStream(android.media.AudioAttributes);
+ method public int getVolumeControlStream();
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -23604,23 +23586,23 @@ package android.media {
}
public final class MediaCas {
- ctor public MediaCas(int) throws android.media.UnsupportedCasException;
+ ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
method public void closeSession(byte[]);
method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
method public static boolean isSystemIdSupported(int);
- method public byte[] openSession(int);
- method public byte[] openSession(int, int);
- method public void processEcm(byte[], byte[], int, int);
- method public void processEcm(byte[], byte[]);
- method public void processEmm(byte[], int, int);
- method public void processEmm(byte[]);
- method public void provision(java.lang.String);
- method public void refreshEntitlements(int, byte[]);
+ method public byte[] openSession(int) throws android.media.MediaCasException;
+ method public byte[] openSession(int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
+ method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
+ method public void processEmm(byte[]) throws android.media.MediaCasException;
+ method public void provision(java.lang.String) throws android.media.MediaCasException;
+ method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
method public void release();
- method public void sendEvent(int, int, byte[]);
+ method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
- method public void setPrivateData(byte[]);
- method public void setSessionPrivateData(byte[], byte[]);
+ method public void setPrivateData(byte[]) throws android.media.MediaCasException;
+ method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
}
public static abstract interface MediaCas.EventListener {
@@ -23633,7 +23615,22 @@ package android.media {
}
public class MediaCasException extends java.lang.Exception {
- ctor public MediaCasException(java.lang.String);
+ }
+
+ public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.ResourceBusyException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.UnsupportedCasException extends android.media.MediaCasException {
+ }
+
+ public class MediaCasStateException extends java.lang.IllegalStateException {
+ method public java.lang.String getDiagnosticInfo();
}
public final class MediaCodec {
@@ -24061,7 +24058,7 @@ package android.media {
}
public final class MediaDescrambler {
- ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException;
+ ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
method public final void release();
method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -25383,10 +25380,6 @@ package android.media {
field public static final int TONE_SUP_RINGTONE = 23; // 0x17
}
- public final class UnsupportedCasException extends android.media.MediaCasException {
- ctor public UnsupportedCasException(java.lang.String);
- }
-
public final class UnsupportedSchemeException extends android.media.MediaDrmException {
ctor public UnsupportedSchemeException(java.lang.String);
}
@@ -26195,9 +26188,9 @@ package android.media.session {
method public void setRepeatMode(int);
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
- field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
- field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+ field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSession.Callback {
@@ -27536,7 +27529,7 @@ package android.net {
method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
method public void removeTunnelModeTransform(android.net.Network, android.net.IpSecTransform);
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+ method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
}
@@ -29350,7 +29343,6 @@ package android.net.wifi.aware {
ctor public PublishConfig.Builder();
method public android.net.wifi.aware.PublishConfig build();
method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(java.util.List<byte[]>);
- method public android.net.wifi.aware.PublishConfig.Builder setPublishCount(int);
method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
method public android.net.wifi.aware.PublishConfig.Builder setServiceName(java.lang.String);
method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(byte[]);
@@ -29379,7 +29371,6 @@ package android.net.wifi.aware {
method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String);
method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]);
- method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeCount(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
@@ -34716,6 +34707,7 @@ package android.os.storage {
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback) throws java.io.IOException;
+ method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler) throws java.io.IOException;
method public void setCacheBehaviorGroup(java.io.File, boolean) throws java.io.IOException;
method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
@@ -34876,6 +34868,7 @@ package android.preference {
method public int getWidgetLayoutResource();
method public boolean hasKey();
method public boolean isEnabled();
+ method public boolean isIconSpaceReserved();
method public boolean isPersistent();
method public boolean isRecycleEnabled();
method public boolean isSelectable();
@@ -34910,6 +34903,7 @@ package android.preference {
method public void setFragment(java.lang.String);
method public void setIcon(android.graphics.drawable.Drawable);
method public void setIcon(int);
+ method public void setIconSpaceReserved(boolean);
method public void setIntent(android.content.Intent);
method public void setKey(java.lang.String);
method public void setLayoutResource(int);
@@ -37748,7 +37742,6 @@ package android.provider {
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
field public static final java.lang.String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
- field public static final java.lang.String ACTION_CONFIGURE_WIFI_SETTINGS = "android.settings.CONFIGURE_WIFI_SETTINGS";
field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
@@ -37798,7 +37791,6 @@ package android.provider {
field public static final java.lang.String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS";
field public static final java.lang.String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS";
field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
- field public static final java.lang.String ACTION_WIFI_SAVED_NETWORK_SETTINGS = "android.settings.WIFI_SAVED_NETWORK_SETTINGS";
field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS";
field public static final java.lang.String ACTION_ZEN_MODE_PRIORITY_SETTINGS = "android.settings.ZEN_MODE_PRIORITY_SETTINGS";
@@ -37871,7 +37863,7 @@ package android.provider {
field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
- field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
+ field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay";
field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
field public static final java.lang.String WIFI_ON = "wifi_on";
@@ -40430,6 +40422,36 @@ package android.service.quicksettings {
}
+package android.service.resolver {
+
+ public abstract class ResolverRankerService extends android.app.Service {
+ ctor public ResolverRankerService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public void onPredictSharingProbabilities(java.util.List<android.service.resolver.ResolverTarget>);
+ method public void onTrainRankingModel(java.util.List<android.service.resolver.ResolverTarget>, int);
+ field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService";
+ }
+
+ public final class ResolverTarget implements android.os.Parcelable {
+ ctor public ResolverTarget();
+ method public int describeContents();
+ method public float getChooserScore();
+ method public float getLaunchScore();
+ method public float getRecencyScore();
+ method public float getSelectProbability();
+ method public float getTimeSpentScore();
+ method public void setChooserScore(float);
+ method public void setLaunchScore(float);
+ method public void setRecencyScore(float);
+ method public void setSelectProbability(float);
+ method public void setTimeSpentScore(float);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.resolver.ResolverTarget> CREATOR;
+ }
+
+}
+
package android.service.restrictions {
public abstract class RestrictionsReceiver extends android.content.BroadcastReceiver {
@@ -40976,6 +40998,7 @@ package android.speech.tts {
method public void onRangeStart(java.lang.String, int, int, int);
method public abstract void onStart(java.lang.String);
method public void onStop(java.lang.String, boolean);
+ method public deprecated void onUtteranceRangeStart(java.lang.String, int, int);
}
public class Voice implements android.os.Parcelable {
@@ -42717,6 +42740,7 @@ package android.telephony {
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -44097,6 +44121,7 @@ package android.test.mock {
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -44203,6 +44228,7 @@ package android.test.mock {
method public byte[] getInstantAppCookie();
method public int getInstantAppCookieMaxSize();
method public android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String);
+ method public android.content.ComponentName getInstantAppResolverSettingsComponent();
method public java.util.List<android.content.pm.InstantAppInfo> getInstantApps();
method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String);
@@ -44516,9 +44542,9 @@ package android.text {
public static final class FontConfig.Font implements android.os.Parcelable {
method public int describeContents();
method public android.text.FontConfig.Axis[] getAxes();
- method public android.os.ParcelFileDescriptor getFd();
method public java.lang.String getFontName();
method public int getTtcIndex();
+ method public android.net.Uri getUri();
method public int getWeight();
method public boolean isItalic();
method public void writeToParcel(android.os.Parcel, int);
@@ -48596,8 +48622,8 @@ package android.view {
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
- method public boolean autofill(android.view.autofill.AutofillValue);
- method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+ method public void autofill(android.view.autofill.AutofillValue);
+ method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -48931,7 +48957,7 @@ package android.view {
method public boolean onKeyUp(int, android.view.KeyEvent);
method protected void onLayout(boolean, int, int, int, int);
method protected void onMeasure(int, int);
- method public void onMovedToDisplay(int);
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
method protected void onOverScrolled(int, int, boolean, boolean);
method public void onPointerCaptureChange(boolean);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -49432,6 +49458,7 @@ package android.view {
method public static deprecated int getEdgeSlop();
method public static deprecated int getFadingEdgeLength();
method public static deprecated long getGlobalActionKeyTimeout();
+ method public float getScaledHorizontalScrollFactor();
method public static int getJumpTapTimeout();
method public static int getKeyRepeatDelay();
method public static int getKeyRepeatTimeout();
@@ -49450,7 +49477,6 @@ package android.view {
method public int getScaledOverscrollDistance();
method public int getScaledPagingTouchSlop();
method public int getScaledScrollBarSize();
- method public int getScaledScrollFactor();
method public int getScaledTouchSlop();
method public int getScaledWindowTouchSlop();
method public static int getScrollBarFadeDuration();
@@ -49459,6 +49485,7 @@ package android.view {
method public static float getScrollFriction();
method public static int getTapTimeout();
method public static deprecated int getTouchSlop();
+ method public float getScaledVerticalScrollFactor();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
method public boolean hasPermanentMenuKey();
@@ -52362,6 +52389,7 @@ package android.webkit {
method public int getRendererRequestedPriority();
method public deprecated float getScale();
method public android.webkit.WebSettings getSettings();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
method public java.lang.String getTitle();
method public java.lang.String getUrl();
method public android.webkit.WebChromeClient getWebChromeClient();
@@ -52409,6 +52437,7 @@ package android.webkit {
method public void setNetworkAvailable(boolean);
method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
method public void setRendererPriorityPolicy(int, boolean);
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
method public deprecated void setVerticalScrollbarOverlay(boolean);
method public void setWebChromeClient(android.webkit.WebChromeClient);
method public static void setWebContentsDebuggingEnabled(boolean);
@@ -52650,6 +52679,7 @@ package android.webkit {
method public abstract float getScale();
method public abstract android.webkit.WebViewProvider.ScrollDelegate getScrollDelegate();
method public abstract android.webkit.WebSettings getSettings();
+ method public default android.view.textclassifier.TextClassifier getTextClassifier();
method public abstract java.lang.String getTitle();
method public abstract java.lang.String getTouchIconUrl();
method public abstract java.lang.String getUrl();
@@ -52702,6 +52732,7 @@ package android.webkit {
method public abstract void setNetworkAvailable(boolean);
method public abstract void setPictureListener(android.webkit.WebView.PictureListener);
method public abstract void setRendererPriorityPolicy(int, boolean);
+ method public default void setTextClassifier(android.view.textclassifier.TextClassifier);
method public abstract void setVerticalScrollbarOverlay(boolean);
method public abstract void setWebChromeClient(android.webkit.WebChromeClient);
method public abstract void setWebViewClient(android.webkit.WebViewClient);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 3aa93982fc94..1244103ee62d 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -368,6 +368,10 @@ package android.view {
method protected void initializeScrollbars(android.content.res.TypedArray);
}
+ public class ViewConfiguration {
+ method public int getScaledScrollFactor();
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 4d8d7f2d5f84..bee9cb31efb5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -696,6 +696,7 @@ package android {
field public static final int hyphenationFrequency = 16843998; // 0x10104de
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
+ field public static final int iconSpaceReserved = 16844132; // 0x1010564
field public static final int iconTint = 16844129; // 0x1010561
field public static final int iconTintMode = 16844130; // 0x1010562
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
@@ -3675,7 +3676,7 @@ package android.app {
method public void onLowMemory();
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
- method public void onMovedToDisplay(int);
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
method public void onMultiWindowModeChanged(boolean);
method public boolean onNavigateUp();
method public boolean onNavigateUpFromChild(android.app.Activity);
@@ -4031,6 +4032,8 @@ package android.app {
method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
method public android.app.ActivityOptions setLaunchDisplayId(int);
method public void setLaunchStackId(int);
+ method public void setLaunchTaskId(int);
+ method public void setTaskOverlay(boolean, boolean);
method public android.os.Bundle toBundle();
method public void update(android.app.ActivityOptions);
field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
@@ -4619,6 +4622,7 @@ package android.app {
method public void onDestroyOptionsMenu();
method public void onDestroyView();
method public void onDetach();
+ method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle);
method public void onHiddenChanged(boolean);
method public deprecated void onInflate(android.util.AttributeSet, android.os.Bundle);
method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
@@ -4773,6 +4777,7 @@ package android.app {
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract java.util.Collection<android.app.Fragment> getFragments();
method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
@@ -5594,7 +5599,7 @@ package android.app {
method public boolean removeAutomaticZenRule(java.lang.String);
method public final void setInterruptionFilter(int);
method public void setNotificationPolicy(android.app.NotificationManager.Policy);
- method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+ method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5649,6 +5654,7 @@ package android.app {
method public java.lang.String getCreatorPackage();
method public int getCreatorUid();
method public android.os.UserHandle getCreatorUserHandle();
+ method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
method public deprecated java.lang.String getTargetPackage();
@@ -7166,7 +7172,6 @@ package android.bluetooth {
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
- method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String);
@@ -8055,21 +8060,6 @@ package android.bluetooth.le {
method public void stopScan(android.bluetooth.le.ScanCallback);
}
- public abstract class PeriodicAdvertisingCallback {
- ctor public PeriodicAdvertisingCallback();
- method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport);
- method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int);
- method public void onSyncLost(int);
- field public static final int SYNC_NO_RESOURCES = 2; // 0x2
- field public static final int SYNC_NO_RESPONSE = 1; // 0x1
- }
-
- public final class PeriodicAdvertisingManager {
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback);
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler);
- method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
- }
-
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
method public int describeContents();
method public boolean getEnable();
@@ -8087,21 +8077,6 @@ package android.bluetooth.le {
method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
}
- public final class PeriodicAdvertisingReport implements android.os.Parcelable {
- ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
- method public int describeContents();
- method public android.bluetooth.le.ScanRecord getData();
- method public int getDataStatus();
- method public int getRssi();
- method public int getSyncHandle();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2
- }
-
public abstract class ScanCallback {
ctor public ScanCallback();
method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
@@ -8885,6 +8860,7 @@ package android.content {
method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
method public abstract void startActivity(android.content.Intent);
method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+ method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9077,6 +9053,7 @@ package android.content {
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -11750,7 +11727,7 @@ package android.database {
}
public final class PageViewCursor extends android.database.CursorWrapper implements android.database.CrossProcessCursor {
- ctor public PageViewCursor(android.database.Cursor, int, int);
+ ctor public PageViewCursor(android.database.Cursor, android.os.Bundle);
method public void fillWindow(int, android.database.CursorWindow);
method public android.database.CursorWindow getWindow();
method public boolean onMove(int, int);
@@ -12743,7 +12720,7 @@ package android.graphics {
enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP;
}
- public class Color {
+ public final class Color {
ctor public Color();
method public static int HSVToColor(float[]);
method public static int HSVToColor(int, float[]);
@@ -12768,6 +12745,7 @@ package android.graphics {
method public float getComponent(int);
method public int getComponentCount();
method public float[] getComponents();
+ method public float[] getComponents(float[]);
method public android.graphics.ColorSpace.Model getModel();
method public float green();
method public static float green(long);
@@ -21000,7 +20978,8 @@ package android.media {
method public int getContentType();
method public int getFlags();
method public int getUsage();
- method public static int getVolumeControlStream(android.media.AudioAttributes);
+ method public static deprecated int getVolumeControlStream(android.media.AudioAttributes);
+ method public int getVolumeControlStream();
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -21929,23 +21908,23 @@ package android.media {
}
public final class MediaCas {
- ctor public MediaCas(int) throws android.media.UnsupportedCasException;
+ ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
method public void closeSession(byte[]);
method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
method public static boolean isSystemIdSupported(int);
- method public byte[] openSession(int);
- method public byte[] openSession(int, int);
- method public void processEcm(byte[], byte[], int, int);
- method public void processEcm(byte[], byte[]);
- method public void processEmm(byte[], int, int);
- method public void processEmm(byte[]);
- method public void provision(java.lang.String);
- method public void refreshEntitlements(int, byte[]);
+ method public byte[] openSession(int) throws android.media.MediaCasException;
+ method public byte[] openSession(int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
+ method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
+ method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
+ method public void processEmm(byte[]) throws android.media.MediaCasException;
+ method public void provision(java.lang.String) throws android.media.MediaCasException;
+ method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
method public void release();
- method public void sendEvent(int, int, byte[]);
+ method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
- method public void setPrivateData(byte[]);
- method public void setSessionPrivateData(byte[], byte[]);
+ method public void setPrivateData(byte[]) throws android.media.MediaCasException;
+ method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
}
public static abstract interface MediaCas.EventListener {
@@ -21958,7 +21937,22 @@ package android.media {
}
public class MediaCasException extends java.lang.Exception {
- ctor public MediaCasException(java.lang.String);
+ }
+
+ public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.ResourceBusyException extends android.media.MediaCasException {
+ }
+
+ public static final class MediaCasException.UnsupportedCasException extends android.media.MediaCasException {
+ }
+
+ public class MediaCasStateException extends java.lang.IllegalStateException {
+ method public java.lang.String getDiagnosticInfo();
}
public final class MediaCodec {
@@ -22386,7 +22380,7 @@ package android.media {
}
public final class MediaDescrambler {
- ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException;
+ ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
method public final void release();
method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -23697,10 +23691,6 @@ package android.media {
field public static final int TONE_SUP_RINGTONE = 23; // 0x17
}
- public final class UnsupportedCasException extends android.media.MediaCasException {
- ctor public UnsupportedCasException(java.lang.String);
- }
-
public final class UnsupportedSchemeException extends android.media.MediaDrmException {
ctor public UnsupportedSchemeException(java.lang.String);
}
@@ -24437,9 +24427,9 @@ package android.media.session {
method public void setRepeatMode(int);
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
- field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
- field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+ field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSession.Callback {
@@ -24659,6 +24649,7 @@ package android.media.tv {
field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+ field public static final java.lang.String COLUMN_TRANSIENT = "transient";
field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
@@ -24736,6 +24727,7 @@ package android.media.tv {
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+ field public static final java.lang.String COLUMN_TRANSIENT = "transient";
field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
@@ -25519,7 +25511,7 @@ package android.net {
method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+ method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
}
@@ -26770,7 +26762,6 @@ package android.net.wifi.aware {
ctor public PublishConfig.Builder();
method public android.net.wifi.aware.PublishConfig build();
method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(java.util.List<byte[]>);
- method public android.net.wifi.aware.PublishConfig.Builder setPublishCount(int);
method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
method public android.net.wifi.aware.PublishConfig.Builder setServiceName(java.lang.String);
method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(byte[]);
@@ -26799,7 +26790,6 @@ package android.net.wifi.aware {
method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String);
method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]);
- method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeCount(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
@@ -32019,6 +32009,7 @@ package android.os.storage {
method public boolean isObbMounted(java.lang.String);
method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback) throws java.io.IOException;
+ method public android.os.ParcelFileDescriptor openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler) throws java.io.IOException;
method public void setCacheBehaviorGroup(java.io.File, boolean) throws java.io.IOException;
method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
@@ -32167,6 +32158,7 @@ package android.preference {
method public int getWidgetLayoutResource();
method public boolean hasKey();
method public boolean isEnabled();
+ method public boolean isIconSpaceReserved();
method public boolean isPersistent();
method public boolean isRecycleEnabled();
method public boolean isSelectable();
@@ -32201,6 +32193,7 @@ package android.preference {
method public void setFragment(java.lang.String);
method public void setIcon(android.graphics.drawable.Drawable);
method public void setIcon(int);
+ method public void setIconSpaceReserved(boolean);
method public void setIntent(android.content.Intent);
method public void setKey(java.lang.String);
method public void setLayoutResource(int);
@@ -34997,7 +34990,7 @@ package android.provider {
field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
- field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
+ field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay";
field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
field public static final java.lang.String WIFI_ON = "wifi_on";
@@ -38043,6 +38036,7 @@ package android.speech.tts {
method public void onRangeStart(java.lang.String, int, int, int);
method public abstract void onStart(java.lang.String);
method public void onStop(java.lang.String, boolean);
+ method public deprecated void onUtteranceRangeStart(java.lang.String, int, int);
}
public class Voice implements android.os.Parcelable {
@@ -39564,6 +39558,7 @@ package android.telephony {
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -40861,6 +40856,7 @@ package android.test.mock {
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -41267,9 +41263,9 @@ package android.text {
public static final class FontConfig.Font implements android.os.Parcelable {
method public int describeContents();
method public android.text.FontConfig.Axis[] getAxes();
- method public android.os.ParcelFileDescriptor getFd();
method public java.lang.String getFontName();
method public int getTtcIndex();
+ method public android.net.Uri getUri();
method public int getWeight();
method public boolean isItalic();
method public void writeToParcel(android.os.Parcel, int);
@@ -45513,8 +45509,8 @@ package android.view {
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
- method public boolean autofill(android.view.autofill.AutofillValue);
- method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+ method public void autofill(android.view.autofill.AutofillValue);
+ method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -45849,7 +45845,7 @@ package android.view {
method public boolean onKeyUp(int, android.view.KeyEvent);
method protected void onLayout(boolean, int, int, int, int);
method protected void onMeasure(int, int);
- method public void onMovedToDisplay(int);
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
method protected void onOverScrolled(int, int, boolean, boolean);
method public void onPointerCaptureChange(boolean);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -46352,6 +46348,7 @@ package android.view {
method public static deprecated int getEdgeSlop();
method public static deprecated int getFadingEdgeLength();
method public static deprecated long getGlobalActionKeyTimeout();
+ method public float getScaledHorizontalScrollFactor();
method public static int getHoverTooltipHideShortTimeout();
method public static int getHoverTooltipHideTimeout();
method public static int getHoverTooltipShowTimeout();
@@ -46374,7 +46371,6 @@ package android.view {
method public int getScaledOverscrollDistance();
method public int getScaledPagingTouchSlop();
method public int getScaledScrollBarSize();
- method public int getScaledScrollFactor();
method public int getScaledTouchSlop();
method public int getScaledWindowTouchSlop();
method public static int getScrollBarFadeDuration();
@@ -46383,6 +46379,7 @@ package android.view {
method public static float getScrollFriction();
method public static int getTapTimeout();
method public static deprecated int getTouchSlop();
+ method public float getScaledVerticalScrollFactor();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
method public boolean hasPermanentMenuKey();
@@ -49192,6 +49189,7 @@ package android.webkit {
method public int getRendererRequestedPriority();
method public deprecated float getScale();
method public android.webkit.WebSettings getSettings();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
method public java.lang.String getTitle();
method public java.lang.String getUrl();
method public android.webkit.WebChromeClient getWebChromeClient();
@@ -49238,6 +49236,7 @@ package android.webkit {
method public void setNetworkAvailable(boolean);
method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
method public void setRendererPriorityPolicy(int, boolean);
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
method public deprecated void setVerticalScrollbarOverlay(boolean);
method public void setWebChromeClient(android.webkit.WebChromeClient);
method public static void setWebContentsDebuggingEnabled(boolean);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 75da976d1b64..fa62e056757c 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -374,6 +374,10 @@ package android.view {
method protected void initializeScrollbars(android.content.res.TypedArray);
}
+ public class ViewConfiguration {
+ method public int getScaledScrollFactor();
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index fa1de030e729..147b5d034fd1 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1990,27 +1990,32 @@ public class Activity extends ContextThemeWrapper
}
}
- void dispatchMovedToDisplay(int displayId) {
+ void dispatchMovedToDisplay(int displayId, Configuration config) {
updateDisplay(displayId);
- onMovedToDisplay(displayId);
+ onMovedToDisplay(displayId, config);
}
/**
* Called by the system when the activity is moved from one display to another without
* recreation. This means that this activity is declared to handle all changes to configuration
* that happened when it was switched to another display, so it wasn't destroyed and created
- * again. This call will be followed by {@link #onConfigurationChanged(Configuration)} if the
- * applied configuration actually changed.
+ * again.
+ *
+ * <p>This call will be followed by {@link #onConfigurationChanged(Configuration)} if the
+ * applied configuration actually changed. It is up to app developer to choose whether to handle
+ * the change in this method or in the following {@link #onConfigurationChanged(Configuration)}
+ * call.
*
* <p>Use this callback to track changes to the displays if some activity functionality relies
* on an association with some display properties.
*
* @param displayId The id of the display to which activity was moved.
+ * @param config Configuration of the activity resources on new display after move.
*
* @see #onConfigurationChanged(Configuration)
- * @see View#onMovedToDisplay(int)
+ * @see View#onMovedToDisplay(int, Configuration)
*/
- public void onMovedToDisplay(int displayId) {
+ public void onMovedToDisplay(int displayId, Configuration config) {
}
/**
@@ -2735,6 +2740,10 @@ public class Activity extends ContextThemeWrapper
return true;
}
return false;
+ } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+ // Don't consume TAB here since it's used for navigation. Arrow keys
+ // aren't considered "typing keys" so they already won't get consumed.
+ return false;
} else {
// Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_*
boolean clearSpannable = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9f2f669b64c8..4004bd6686b1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -405,6 +405,13 @@ public class ActivityManager {
*/
public static final int INTENT_SENDER_SERVICE = 4;
+ /**
+ * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * for a startForegroundService operation.
+ * @hide
+ */
+ public static final int INTENT_SENDER_FOREGROUND_SERVICE = 5;
+
/** @hide User operation call: success! */
public static final int USER_OP_SUCCESS = 0;
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 0b9479d8b52e..aa7cdf7b475e 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1068,6 +1068,7 @@ public class ActivityOptions {
* Sets the task the activity will be launched in.
* @hide
*/
+ @TestApi
public void setLaunchTaskId(int taskId) {
mLaunchTaskId = taskId;
}
@@ -1085,6 +1086,7 @@ public class ActivityOptions {
* the task will also not be moved to the front of the stack.
* @hide
*/
+ @TestApi
public void setTaskOverlay(boolean taskOverlay, boolean canResume) {
mTaskOverlay = taskOverlay;
mTaskOverlayCanResume = canResume;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b4e6bd5856c7..b5d1fa8550df 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -808,11 +808,6 @@ public final class ActivityThread {
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
- // TODO: Debugging added for bug:36406078 . Remove when done
- if (Log.isLoggable("36406078", Log.DEBUG)) {
- Log.d(TAG, "scheduleReceiver");
- }
-
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
@@ -899,11 +894,6 @@ public final class ActivityThread {
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) {
- // TODO: Debugging added for bug:36406078 . Remove when done
- if (Log.isLoggable("36406078", Log.DEBUG)) {
- Log.d(TAG, "bindApplication: " + processName);
- }
-
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
@@ -3239,10 +3229,6 @@ public final class ActivityThread {
if (receiver.getPendingResult() != null) {
data.finish();
}
- // TODO: Debugging added for bug:36406078 . Remove when done
- if (Log.isLoggable("36406078", Log.DEBUG)) {
- Log.d(TAG, "handleReceiver done");
- }
}
// Instantiate a BackupAgent and tell it that it's alive
@@ -4815,16 +4801,18 @@ public final class ActivityThread {
* {@link ActivityClientRecord#overrideConfig}.
* @param displayId The id of the display where the Activity currently resides.
* @param movedToDifferentDisplay Indicates if the activity was moved to different display.
+ * @return {@link Configuration} instance sent to client, null if not sent.
*/
- private void performConfigurationChangedForActivity(ActivityClientRecord r,
+ private Configuration performConfigurationChangedForActivity(ActivityClientRecord r,
Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) {
r.tmpConfig.setTo(newBaseConfig);
if (r.overrideConfig != null) {
r.tmpConfig.updateFrom(r.overrideConfig);
}
- performActivityConfigurationChanged(r.activity, r.tmpConfig, r.overrideConfig, displayId,
- movedToDifferentDisplay);
+ final Configuration reportedConfig = performActivityConfigurationChanged(r.activity,
+ r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay);
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
+ return reportedConfig;
}
/**
@@ -4878,9 +4866,11 @@ public final class ActivityThread {
* ActivityManager.
* @param displayId Id of the display where activity currently resides.
* @param movedToDifferentDisplay Indicates if the activity was moved to different display.
+ * @return Configuration sent to client, null if no changes and not moved to different display.
*/
- private void performActivityConfigurationChanged(Activity activity, Configuration newConfig,
- Configuration amOverrideConfig, int displayId, boolean movedToDifferentDisplay) {
+ private Configuration performActivityConfigurationChanged(Activity activity,
+ Configuration newConfig, Configuration amOverrideConfig, int displayId,
+ boolean movedToDifferentDisplay) {
if (activity == null) {
throw new IllegalArgumentException("No activity provided.");
}
@@ -4911,7 +4901,7 @@ public final class ActivityThread {
}
if (!shouldChangeConfig && !movedToDifferentDisplay) {
// Nothing significant, don't proceed with updating and reporting.
- return;
+ return null;
}
// Propagate the configuration change to ResourcesManager and Activity.
@@ -4934,22 +4924,22 @@ public final class ActivityThread {
activity.mConfigChangeFlags = 0;
activity.mCurrentConfig = new Configuration(newConfig);
+ // Apply the ContextThemeWrapper override if necessary.
+ // NOTE: Make sure the configurations are not modified, as they are treated as immutable
+ // in many places.
+ final Configuration configToReport = createNewConfigAndUpdateIfNotNull(newConfig,
+ contextThemeWrapperOverrideConfig);
+
if (!REPORT_TO_ACTIVITY) {
// Not configured to report to activity.
- return;
+ return configToReport;
}
if (movedToDifferentDisplay) {
- activity.dispatchMovedToDisplay(displayId);
+ activity.dispatchMovedToDisplay(displayId, configToReport);
}
if (shouldChangeConfig) {
- // Apply the ContextThemeWrapper override if necessary.
- // NOTE: Make sure the configurations are not modified, as they are treated as immutable
- // in many places.
- final Configuration configToReport = createNewConfigAndUpdateIfNotNull(
- newConfig, contextThemeWrapperOverrideConfig);
-
activity.mCalled = false;
activity.onConfigurationChanged(configToReport);
if (!activity.mCalled) {
@@ -4957,6 +4947,8 @@ public final class ActivityThread {
" did not call through to super.onConfigurationChanged()");
}
}
+
+ return configToReport;
}
public final void applyConfigurationToResources(Configuration config) {
@@ -5129,10 +5121,10 @@ public final class ActivityThread {
+ r.activityInfo.name + ", displayId=" + displayId
+ ", config=" + data.overrideConfig);
- performConfigurationChangedForActivity(r, mCompatConfiguration, displayId,
- true /* movedToDifferentDisplay */);
+ final Configuration reportedConfig = performConfigurationChangedForActivity(r,
+ mCompatConfiguration, displayId, true /* movedToDifferentDisplay */);
if (viewRoot != null) {
- viewRoot.onMovedToDisplay(displayId);
+ viewRoot.onMovedToDisplay(displayId, reportedConfig);
}
} else {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
@@ -5142,7 +5134,7 @@ public final class ActivityThread {
// Notify the ViewRootImpl instance about configuration changes. It may have initiated this
// update to make sure that resources are updated before updating itself.
if (viewRoot != null) {
- viewRoot.updateConfiguration();
+ viewRoot.updateConfiguration(displayId);
}
mSomeActivitiesChanged = true;
}
@@ -5778,10 +5770,6 @@ public final class ActivityThread {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- // TODO: Debugging added for bug:36406078 . Remove when done
- if (Log.isLoggable("36406078", Log.DEBUG)) {
- Log.d(TAG, "handleBindApplication done");
- }
}
/*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index ef2db4a0d795..2062930929a2 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -18,6 +18,7 @@ package android.app;
import android.os.Build;
import android.os.Trace;
+import android.text.TextUtils;
import android.util.ArrayMap;
import com.android.internal.os.PathClassLoaderFactory;
import dalvik.system.PathClassLoader;
@@ -29,8 +30,16 @@ public class ApplicationLoaders {
}
ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
- String librarySearchPath, String libraryPermittedPath,
- ClassLoader parent) {
+ String librarySearchPath, String libraryPermittedPath,
+ ClassLoader parent) {
+ // For normal usage the cache key used is the same as the zip path.
+ return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath,
+ libraryPermittedPath, parent, zip);
+ }
+
+ private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
+ String librarySearchPath, String libraryPermittedPath,
+ ClassLoader parent, String cacheKey) {
/*
* This is the parent we use if they pass "null" in. In theory
* this should be the "system" class loader; in practice we
@@ -50,7 +59,7 @@ public class ApplicationLoaders {
* new ClassLoader for the zip archive.
*/
if (parent == baseParent) {
- ClassLoader loader = mLoaders.get(zip);
+ ClassLoader loader = mLoaders.get(cacheKey);
if (loader != null) {
return loader;
}
@@ -71,7 +80,7 @@ public class ApplicationLoaders {
setupVulkanLayerPath(pathClassloader, librarySearchPath);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- mLoaders.put(zip, pathClassloader);
+ mLoaders.put(cacheKey, pathClassloader);
return pathClassloader;
}
@@ -87,12 +96,16 @@ public class ApplicationLoaders {
* by this class. This is used in the WebView zygote, where its presence in the cache speeds up
* startup and enables memory sharing.
*/
- public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath) {
- // The correct paths are calculated by WebViewZygote in the system server and passed to
- // us here. We hardcode the other parameters: WebView always targets the current SDK,
- // does not need to use non-public system libraries, and uses the base classloader as its
- // parent to permit usage of the cache.
- return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null);
+ public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath,
+ String cacheKey) {
+ // The correct paths are calculated by WebViewZygote in the system server and passed to
+ // us here. We hardcode the other parameters: WebView always targets the current SDK,
+ // does not need to use non-public system libraries, and uses the base classloader as its
+ // parent to permit usage of the cache.
+ // The cache key is passed separately to enable the stub WebView to be cached under the
+ // stub's APK path, when the actual package path is the donor APK.
+ return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null,
+ cacheKey);
}
private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 286f8570f55c..461f9cc35125 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2630,4 +2630,13 @@ public class ApplicationPackageManager extends PackageManager {
throw e.rethrowAsRuntimeException();
}
}
+
+ @Override
+ public ComponentName getInstantAppResolverSettingsComponent() {
+ try {
+ return mPM.getInstantAppResolverSettingsComponent();
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4c080c9e6a95..467ba996ad4f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1447,14 +1447,21 @@ class ContextImpl extends Context {
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
- return startServiceCommon(service, -1, null, mUser);
+ return startServiceCommon(service, -1, null, false, mUser);
}
@Override
+ public ComponentName startForegroundService(Intent service) {
+ warnIfCallingFromSystemProcess();
+ return startServiceCommon(service, -1, null, true, mUser);
+ }
+
+ // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
+ @Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
warnIfCallingFromSystemProcess();
- return startServiceCommon(service, id, notification, mUser);
+ return startServiceCommon(service, id, notification, false, mUser);
}
@Override
@@ -1465,24 +1472,30 @@ class ContextImpl extends Context {
@Override
public ComponentName startServiceAsUser(Intent service, UserHandle user) {
- return startServiceCommon(service, -1, null, user);
+ return startServiceCommon(service, -1, null, false, user);
}
@Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ return startServiceCommon(service, -1, null, true, user);
+ }
+
+ // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
+ @Override
public ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user) {
- return startServiceCommon(service, id, notification, user);
+ return startServiceCommon(service, id, notification, false, user);
}
private ComponentName startServiceCommon(Intent service, int id, Notification notification,
- UserHandle user) {
+ boolean requireForeground, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
- getContentResolver()), id, notification, getOpPackageName(),
- user.getIdentifier());
+ getContentResolver()), id, notification, requireForeground,
+ getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index 3198c7c086d1..7e0e4d827477 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -398,9 +398,9 @@ public class DialogFragment extends Fragment
/** @hide */
@Override
- public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
+ public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
if (!mShowsDialog) {
- return super.getLayoutInflater(savedInstanceState);
+ return super.onGetLayoutInflater(savedInstanceState);
}
mDialog = onCreateDialog(savedInstanceState);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 44fefd38048c..02fe101c9152 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -31,7 +31,6 @@ import android.content.res.TypedArray;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
-import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1357,11 +1356,16 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
}
/**
- * @hide Hack so that DialogFragment can make its Dialog before creating
- * its views, and the view construction can use the dialog's context for
- * inflation. Maybe this should become a public API. Note sure.
+ * Returns the LayoutInflater used to inflate Views of this Fragment. The default
+ * implementation will throw an exception if the Fragment is not attached.
+ *
+ * @return The LayoutInflater used to inflate Views of this Fragment.
*/
- public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
+ public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
+ if (mHost == null) {
+ throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the "
+ + "Fragment is attached to the FragmentManager.");
+ }
final LayoutInflater result = mHost.onGetLayoutInflater();
if (mHost.onUseFragmentManagerInflaterFactory()) {
getChildFragmentManager(); // Init if needed; use raw implementation below.
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index d710d8bb6221..0c1be07ab231 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -54,6 +54,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -312,6 +314,16 @@ public abstract class FragmentManager {
public abstract Fragment getFragment(Bundle bundle, String key);
/**
+ * Get a collection of all fragments that are currently added to the FragmentManager.
+ * This may include those that are hidden as well as those that are shown.
+ * This will not include any fragments only in the back stack, or fragments that
+ * are detached or removed.
+ *
+ * @return A collection of all fragments that are added to the FragmentManager.
+ */
+ public abstract Collection<Fragment> getFragments();
+
+ /**
* Save the current instance state of the given Fragment. This can be
* used later when creating a new instance of the Fragment and adding
* it to the fragment manager, to have it create itself to match the
@@ -895,6 +907,16 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
@Override
+ public Collection<Fragment> getFragments() {
+ if (mAdded == null) {
+ return Collections.EMPTY_LIST;
+ }
+ synchronized (mAdded) {
+ return (Collection<Fragment>) mAdded.clone();
+ }
+ }
+
+ @Override
public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
if (fragment.mIndex < 0) {
throwException(new IllegalStateException("Fragment " + fragment
@@ -1226,7 +1248,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
}
f.mContainer = container;
- f.mView = f.performCreateView(f.getLayoutInflater(
+ f.mView = f.performCreateView(f.onGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mView.setSaveFromParentEnabled(false);
@@ -1398,7 +1420,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
void ensureInflatedFragmentView(Fragment f) {
if (f.mFromLayout && !f.mPerformedCreateView) {
- f.mView = f.performCreateView(f.getLayoutInflater(
+ f.mView = f.performCreateView(f.onGetLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
f.mView.setSaveFromParentEnabled(false);
@@ -1620,7 +1642,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
- mAdded.add(fragment);
+ synchronized (mAdded) {
+ mAdded.add(fragment);
+ }
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mView == null) {
@@ -1648,7 +1672,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
}
if (mAdded != null) {
- mAdded.remove(fragment);
+ synchronized (mAdded) {
+ mAdded.remove(fragment);
+ }
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
@@ -1698,7 +1724,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
// We are not already in back stack, so need to remove the fragment.
if (mAdded != null) {
if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
- mAdded.remove(fragment);
+ synchronized (mAdded) {
+ mAdded.remove(fragment);
+ }
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
@@ -1720,7 +1748,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
throw new IllegalStateException("Fragment already added: " + fragment);
}
if (DEBUG) Log.v(TAG, "add from attach: " + fragment);
- mAdded.add(fragment);
+ synchronized (mAdded) {
+ mAdded.add(fragment);
+ }
fragment.mAdded = true;
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
@@ -2695,7 +2725,15 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
for (int i = 0; i < count; i++) {
Fragment f = nonConfigFragments.get(i);
if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
- FragmentState fs = fms.mActive[f.mIndex];
+ int index = 0; // index of f in fms.mActive
+ while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) {
+ index++;
+ }
+ if (index == fms.mActive.length) {
+ throwException(new IllegalStateException("Could not find active fragment "
+ + "with index " + f.mIndex));
+ }
+ FragmentState fs = fms.mActive[index];
fs.mInstance = f;
f.mSavedViewState = null;
f.mBackStackNesting = 0;
@@ -2762,7 +2800,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
if (mAdded.contains(f)) {
throw new IllegalStateException("Already added!");
}
- mAdded.add(f);
+ synchronized (mAdded) {
+ mAdded.add(f);
+ }
}
} else {
mAdded = null;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 82229d5b1bc8..0a5e4bef8dca 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -130,7 +130,7 @@ interface IActivityManager {
PendingIntent getRunningServiceControlPanel(in ComponentName service);
ComponentName startService(in IApplicationThread caller, in Intent service,
in String resolvedType, int id, in Notification notification,
- in String callingPackage, int userId);
+ boolean requireForeground, in String callingPackage, int userId);
int stopService(in IApplicationThread caller, in Intent service,
in String resolvedType, int userId);
int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
@@ -629,6 +629,11 @@ interface IActivityManager {
*/
void setDisablePreviewScreenshots(IBinder token, boolean disable);
+ /**
+ * Return the user id of last resumed activity.
+ */
+ int getLastResumedActivityUserId();
+
// WARNING: when these transactions are updated, check if they are any callers on the native
// side. If so, make sure they are using the correct transaction ids and arguments.
// If a transaction which will also be used on the native side is being inserted, add it
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c78b3cde6fbe..4bbc003cfdfa 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -971,6 +971,7 @@ public class Notification implements Parcelable
* Only available to notifications coming from the android package.
* @hide
*/
+ @SystemApi
public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
/**
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 75998f2eb36d..72c59781ae80 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1171,8 +1171,11 @@ public class NotificationManager
* @return If the service is being started or is already running, the
* {@link ComponentName} of the actual service that was started is
* returned; else if the service does not exist null is returned.
+ *
+ * @deprecated STOPSHIP transition away from this for O
*/
@Nullable
+ @Deprecated
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
return mContext.startServiceInForeground(service, id, notification);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 7d1a16ab1045..dc432afb5c06 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -596,6 +596,42 @@ public final class PendingIntent implements Parcelable {
*/
public static PendingIntent getService(Context context, int requestCode,
@NonNull Intent intent, @Flags int flags) {
+ return buildServicePendingIntent(context, requestCode, intent, flags,
+ ActivityManager.INTENT_SENDER_SERVICE);
+ }
+
+ /**
+ * Retrieve a PendingIntent that will start a foreground service, like calling
+ * {@link Context#startService Context.startForegroundService()}. The start
+ * arguments given to the service will come from the extras of the Intent.
+ *
+ * <p class="note">For security reasons, the {@link android.content.Intent}
+ * you supply here should almost always be an <em>explicit intent</em>,
+ * that is specify an explicit component to be delivered to through
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
+ *
+ * @param context The Context in which this PendingIntent should start
+ * the service.
+ * @param requestCode Private request code for the sender
+ * @param intent An Intent describing the service to be started.
+ * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
+ * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
+ * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
+ * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
+ * of the intent that can be supplied when the actual send happens.
+ *
+ * @return Returns an existing or new PendingIntent matching the given
+ * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
+ * supplied.
+ */
+ public static PendingIntent getForegroundService(Context context, int requestCode,
+ @NonNull Intent intent, @Flags int flags) {
+ return buildServicePendingIntent(context, requestCode, intent, flags,
+ ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE);
+ }
+
+ private static PendingIntent buildServicePendingIntent(Context context, int requestCode,
+ Intent intent, int flags, int serviceKind) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
@@ -603,7 +639,7 @@ public final class PendingIntent implements Parcelable {
intent.prepareToLeaveProcess(context);
IIntentSender target =
ActivityManager.getService().getIntentSender(
- ActivityManager.INTENT_SENDER_SERVICE, packageName,
+ serviceKind, packageName,
null, null, requestCode, new Intent[] { intent },
resolvedType != null ? new String[] { resolvedType } : null,
flags, null, UserHandle.myUserId());
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 124749a43d61..9b349dd85614 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -74,7 +74,9 @@ import android.net.ConnectivityThread;
import android.net.EthernetManager;
import android.net.IConnectivityManager;
import android.net.IEthernetManager;
+import android.net.IIpSecService;
import android.net.INetworkPolicyManager;
+import android.net.IpSecManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkScoreManager;
import android.net.nsd.INsdManager;
@@ -93,6 +95,7 @@ import android.nfc.NfcManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Build;
+import android.os.Debug;
import android.os.DropBoxManager;
import android.os.HardwarePropertiesManager;
import android.os.IBatteryPropertiesRegistrar;
@@ -262,6 +265,15 @@ final class SystemServiceRegistry {
return new ConnectivityManager(context, service);
}});
+ registerService(Context.IPSEC_SERVICE, IpSecManager.class,
+ new StaticServiceFetcher<IpSecManager>() {
+ @Override
+ public IpSecManager createService() {
+ IBinder b = ServiceManager.getService(Context.IPSEC_SERVICE);
+ IIpSecService service = IIpSecService.Stub.asInterface(b);
+ return new IpSecManager(service);
+ }});
+
registerService(Context.COUNTRY_DETECTOR, CountryDetector.class,
new StaticServiceFetcher<CountryDetector>() {
@Override
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6e31d807a044..1ca2be5b2a1f 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -612,6 +612,51 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
+ * Enables the optional codecs.
+ *
+ * @hide
+ */
+ public void enableOptionalCodecs() {
+ if (DBG) Log.d(TAG, "enableOptionalCodecs");
+ enableDisableOptionalCodecs(true);
+ }
+
+ /**
+ * Disables the optional codecs.
+ *
+ * @hide
+ */
+ public void disableOptionalCodecs() {
+ if (DBG) Log.d(TAG, "disableOptionalCodecs");
+ enableDisableOptionalCodecs(false);
+ }
+
+ /**
+ * Enables or disables the optional codecs.
+ *
+ * @param enable if true, enable the optional codecs, other disable them
+ */
+ private void enableDisableOptionalCodecs(boolean enable) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()) {
+ if (enable) {
+ mService.enableOptionalCodecs();
+ } else {
+ mService.disableOptionalCodecs();
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error talking to BT service in enableDisableOptionalCodecs()", e);
+ return;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
* Helper for converting a state to a string.
*
* For debug use only - strings are not internationalized.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 4e1e42da4fe7..845a47d99842 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -638,6 +638,7 @@ public final class BluetoothAdapter {
* <p>
* Use {@link #isLePeriodicAdvertisingSupported()} to check whether LE Periodic Advertising is
* supported on this device before calling this method.
+ * @hide
*/
public PeriodicAdvertisingManager getPeriodicAdvertisingManager() {
if (!getLeAccess())
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index 176e48fb6e08..d5e142981013 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -63,7 +63,7 @@ public final class BluetoothCodecConfig implements Parcelable {
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
private final int mCodecType;
- private final int mCodecPriority;
+ private int mCodecPriority;
private final int mSampleRate;
private final int mBitsPerSample;
private final int mChannelMode;
@@ -280,6 +280,15 @@ public final class BluetoothCodecConfig implements Parcelable {
}
/**
+ * Checks whether the codec is mandatory.
+ *
+ * @return true if the codec is mandatory, otherwise false.
+ */
+ public boolean isMandatoryCodec() {
+ return mCodecType == SOURCE_CODEC_TYPE_SBC;
+ }
+
+ /**
* Gets the codec selection priority.
* The codec selection priority is relative to other codecs: larger value
* means higher priority. If 0, reset to default.
@@ -291,6 +300,17 @@ public final class BluetoothCodecConfig implements Parcelable {
}
/**
+ * Sets the codec selection priority.
+ * The codec selection priority is relative to other codecs: larger value
+ * means higher priority. If 0, reset to default.
+ *
+ * @param codecPriority the codec priority
+ */
+ public void setCodecPriority(int codecPriority) {
+ mCodecPriority = codecPriority;
+ }
+
+ /**
* Gets the codec sample rate. The value can be a bitmask with all
* supported sample rates:
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 9e2eb84b13f9..5d1e8ec58ceb 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -135,8 +135,8 @@ public final class BluetoothGatt implements BluetoothProfile {
/**
* Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
*/
- private final IBluetoothGattCallbackExt mBluetoothGattCallback =
- new IBluetoothGattCallbackExt.Stub() {
+ private final IBluetoothGattCallback mBluetoothGattCallback =
+ new IBluetoothGattCallback.Stub() {
/**
* Application interface registered - app is ready to go
* @hide
@@ -778,7 +778,7 @@ public final class BluetoothGatt implements BluetoothProfile {
/**
* Set the preferred connection PHY for this app. Please note that this is just a
- * recommendation, wether the PHY change will happen depends on other applications peferences,
+ * recommendation, whether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
* {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index c991e2f71bb8..2df2ed8ff86f 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -59,8 +59,8 @@ public final class BluetoothGattServer implements BluetoothProfile {
/**
* Bluetooth GATT interface callbacks
*/
- private final IBluetoothGattServerCallbackExt mBluetoothGattServerCallback =
- new IBluetoothGattServerCallbackExt.Stub() {
+ private final IBluetoothGattServerCallback mBluetoothGattServerCallback =
+ new IBluetoothGattServerCallback.Stub() {
/**
* Application interface registered - app is ready to go
* @hide
@@ -550,7 +550,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
/**
* Set the preferred connection PHY for this app. Please note that this is just a
- * recommendation, wether the PHY change will happen depends on other applications peferences,
+ * recommendation, whether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
* {@link BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index dbb5b7d7944b..a775a1f90b8e 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -40,4 +40,6 @@ interface IBluetoothA2dp {
boolean isA2dpPlaying(in BluetoothDevice device);
BluetoothCodecStatus getCodecStatus();
oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig);
+ oneway void enableOptionalCodecs();
+ oneway void disableOptionalCodecs();
}
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 652a1c6098f2..0825ee88a456 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -29,8 +29,8 @@ import android.bluetooth.le.ResultStorageDescriptor;
import android.os.ParcelUuid;
import android.os.WorkSource;
-import android.bluetooth.IBluetoothGattCallbackExt;
-import android.bluetooth.IBluetoothGattServerCallbackExt;
+import android.bluetooth.IBluetoothGattCallback;
+import android.bluetooth.IBluetoothGattServerCallback;
import android.bluetooth.le.IAdvertiserCallback;
import android.bluetooth.le.IAdvertisingSetCallback;
import android.bluetooth.le.IPeriodicAdvertisingCallback;
@@ -66,7 +66,7 @@ interface IBluetoothGatt {
void registerSync(in ScanResult scanResult, in int skip, in int timeout, in IPeriodicAdvertisingCallback callback);
void unregisterSync(in IPeriodicAdvertisingCallback callback);
- void registerClient(in ParcelUuid appId, in IBluetoothGattCallbackExt callback);
+ void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
void unregisterClient(in int clientIf);
void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport, in int phy);
@@ -88,7 +88,7 @@ interface IBluetoothGatt {
void configureMTU(in int clientIf, in String address, in int mtu);
void connectionParameterUpdate(in int clientIf, in String address, in int connectionPriority);
- void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallbackExt callback);
+ void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback);
void unregisterServer(in int serverIf);
void serverConnect(in int serverIf, in String address, in boolean isDirect, in int transport);
void serverDisconnect(in int serverIf, in String address);
diff --git a/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index ed69e54671ca..4f85cdda87f7 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -22,7 +22,7 @@ import android.bluetooth.BluetoothGattService;
* Callback definitions for interacting with BLE / GATT
* @hide
*/
-oneway interface IBluetoothGattCallbackExt {
+oneway interface IBluetoothGattCallback {
void onClientRegistered(in int status, in int clientIf);
void onClientConnectionState(in int status, in int clientIf,
in boolean connected, in String address);
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
index 267e8824439d..74ee11fbd321 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -21,7 +21,7 @@ import android.bluetooth.BluetoothGattService;
* Callback definitions for interacting with BLE / GATT
* @hide
*/
-oneway interface IBluetoothGattServerCallbackExt {
+oneway interface IBluetoothGattServerCallback {
void onServerRegistered(in int status, in int serverIf);
void onServerConnectionState(in int status, in int serverIf,
in boolean connected, in String address);
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index fe1f425c4fc1..3e13ad34f019 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -253,10 +253,10 @@ public final class AdvertisingSetParameters implements Parcelable {
/**
* Set whether the advertisement type should be connectable or
* non-connectable.
- * Legacy advertisements can be both connectable and scannable. Other
- * advertisements can be connectable only if not scannable.
+ * Legacy advertisements must be both connectable and scannable. Nonlegacy
+ * advertisements can be only scannable or only connectable.
* @param connectable Controls whether the advertisment type will be
- * connectable (true) or non-connectable (false).
+ * connectable (true) or nonconnectable (false).
*/
public Builder setConnectable(boolean connectable) {
this.connectable = connectable;
@@ -264,11 +264,11 @@ public final class AdvertisingSetParameters implements Parcelable {
}
/**
- * Set whether the advertisement type should be scannable
- * Legacy advertisements can be both connectable and scannable. Other
- * advertisements can be scannable only if not connectable.
+ * Set whether the advertisement type should be scannable.
+ * Legacy advertisements must be both connectable and scannable. Nonlegacy
+ * advertisements can be only scannable or only connectable.
* @param scannable Controls whether the advertisment type will be
- * scannable (true) or non-scannable (false).
+ * scannable (true) or nonscannable (false).
*/
public Builder setScannable(boolean scannable) {
this.scannable = scannable;
@@ -279,7 +279,7 @@ public final class AdvertisingSetParameters implements Parcelable {
* When set to true, advertising set will advertise 4.x Spec compliant
* advertisements.
*
- * @param isLegacy wether legacy advertising mode should be used.
+ * @param isLegacy whether legacy advertising mode should be used.
*/
public Builder setLegacyMode(boolean isLegacy) {
this.isLegacy = isLegacy;
@@ -287,12 +287,12 @@ public final class AdvertisingSetParameters implements Parcelable {
}
/**
- * Set wether advertiser address should be ommited from all packets. If this
+ * Set whether advertiser address should be ommited from all packets. If this
* mode is used, periodic advertising can't be enabled for this set.
*
* This is used only if legacy mode is not used.
*
- * @param isAnonymous wether anonymous advertising should be used.
+ * @param isAnonymous whether anonymous advertising should be used.
*/
public Builder setAnonymous(boolean isAnonymous) {
this.isAnonymous = isAnonymous;
@@ -300,11 +300,11 @@ public final class AdvertisingSetParameters implements Parcelable {
}
/**
- * Set wether TX power should be included in the extended header.
+ * Set whether TX power should be included in the extended header.
*
* This is used only if legacy mode is not used.
*
- * @param includeTxPower wether TX power should be included in extended
+ * @param includeTxPower whether TX power should be included in extended
* header
*/
public Builder setIncludeTxPower(boolean includeTxPower) {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
index 6616231bcdf8..364b575b4d8d 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
@@ -23,6 +23,7 @@ import android.bluetooth.BluetoothDevice;
* advertising operation status.
*
* @see PeriodicAdvertisingManager#createSync
+ * @hide
*/
public abstract class PeriodicAdvertisingCallback {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
index 12c8a8c8ffd4..d9c2d8819a33 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
@@ -37,6 +37,7 @@ import java.util.Map;
* <p>
* <b>Note:</b> Most of the methods here require
* {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ * @hide
*/
public final class PeriodicAdvertisingManager {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
index ebc92bd0bcf8..149540ce0dab 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
@@ -93,7 +93,7 @@ public final class PeriodicAdvertisingParameters implements Parcelable {
private int interval = INTERVAL_MAX;
/**
- * Set wether the Periodic Advertising should be enabled for this set.
+ * Set whether the Periodic Advertising should be enabled for this set.
*/
public Builder setEnable(boolean enable) {
this.enable = enable;
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
index 3ff4ca580069..51b93cbd64dc 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
@@ -24,6 +24,7 @@ import java.util.Objects;
/**
* PeriodicAdvertisingReport for Bluetooth LE synchronized advertising.
+ * @hide
*/
public final class PeriodicAdvertisingReport implements Parcelable {
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index bb844a327168..919f4baf3b86 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -27,6 +27,7 @@ import com.android.internal.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* A request for the user to select a companion device to associate with.
@@ -69,6 +70,20 @@ public final class AssociationRequest implements Parcelable {
}
@Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AssociationRequest that = (AssociationRequest) o;
+ return mSingleDevice == that.mSingleDevice &&
+ Objects.equals(mDeviceFilters, that.mDeviceFilters);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSingleDevice, mDeviceFilters);
+ }
+
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (mSingleDevice ? 1 : 0));
dest.writeParcelableList(mDeviceFilters, flags);
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
index 1d8df7f26f6e..84e15364c191 100644
--- a/core/java/android/companion/BluetoothDeviceFilter.java
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -35,6 +35,7 @@ import com.android.internal.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.regex.Pattern;
/**
@@ -123,6 +124,22 @@ public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice
}
@Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ BluetoothDeviceFilter that = (BluetoothDeviceFilter) o;
+ return Objects.equals(mNamePattern, that.mNamePattern) &&
+ Objects.equals(mAddress, that.mAddress) &&
+ Objects.equals(mServiceUuids, that.mServiceUuids) &&
+ Objects.equals(mServiceUuidMasks, that.mServiceUuidMasks);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mNamePattern, mAddress, mServiceUuids, mServiceUuidMasks);
+ }
+
+ @Override
public int describeContents() {
return 0;
}
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 8a316f19af8e..3665d1b85bcb 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -37,7 +37,7 @@ public class BluetoothDeviceFilterUtils {
private BluetoothDeviceFilterUtils() {}
private static final boolean DEBUG = false;
- private static final String LOG_TAG = "BluetoothDeviceFilterUtil";
+ private static final String LOG_TAG = "BluetoothDeviceFilterUtils";
@Nullable
static String patternToString(@Nullable Pattern p) {
@@ -50,8 +50,10 @@ public class BluetoothDeviceFilterUtils {
}
static boolean matches(ScanFilter filter, BluetoothDevice device) {
- return matchesAddress(filter.getDeviceAddress(), device)
+ boolean result = matchesAddress(filter.getDeviceAddress(), device)
&& matchesServiceUuid(filter.getServiceUuid(), filter.getServiceUuidMask(), device);
+ if (DEBUG) debugLogMatchResult(result, device, filter);
+ return result;
}
static boolean matchesAddress(String deviceAddress, BluetoothDevice device) {
diff --git a/core/java/android/companion/BluetoothLEDeviceFilter.java b/core/java/android/companion/BluetoothLEDeviceFilter.java
index e057fbcc901a..5a1b29d63e10 100644
--- a/core/java/android/companion/BluetoothLEDeviceFilter.java
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.java
@@ -31,11 +31,14 @@ import android.bluetooth.le.ScanResult;
import android.os.Parcel;
import android.provider.OneTimeUseBuilder;
import android.text.TextUtils;
+import android.util.Log;
import com.android.internal.util.BitUtils;
import com.android.internal.util.ObjectUtils;
import com.android.internal.util.Preconditions;
+import java.util.Arrays;
+import java.util.Objects;
import java.util.regex.Pattern;
/**
@@ -45,6 +48,9 @@ import java.util.regex.Pattern;
*/
public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = "BluetoothLEDeviceFilter";
+
private static final int RENAME_PREFIX_LENGTH_LIMIT = 10;
private final Pattern mNamePattern;
@@ -143,9 +149,13 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
/** @hide */
@Override
public boolean matches(ScanResult device) {
- return matches(device.getDevice())
- && BitUtils.maskedEquals(device.getScanRecord().getBytes(),
- mRawDataFilter, mRawDataFilterMask);
+ boolean result = matches(device.getDevice())
+ && (mRawDataFilter == null
+ || BitUtils.maskedEquals(device.getScanRecord().getBytes(),
+ mRawDataFilter, mRawDataFilterMask));
+ if (DEBUG) Log.i(LOG_TAG, "matches(this = " + this + ", device = " + device +
+ ") -> " + result);
+ return result;
}
private boolean matches(BluetoothDevice device) {
@@ -160,9 +170,39 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
}
@Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ BluetoothLEDeviceFilter that = (BluetoothLEDeviceFilter) o;
+ return mRenameBytesFrom == that.mRenameBytesFrom &&
+ mRenameBytesTo == that.mRenameBytesTo &&
+ mRenameBytesReverseOrder == that.mRenameBytesReverseOrder &&
+ Objects.equals(mNamePattern, that.mNamePattern) &&
+ Objects.equals(mScanFilter, that.mScanFilter) &&
+ Arrays.equals(mRawDataFilter, that.mRawDataFilter) &&
+ Arrays.equals(mRawDataFilterMask, that.mRawDataFilterMask) &&
+ Objects.equals(mRenamePrefix, that.mRenamePrefix) &&
+ Objects.equals(mRenameSuffix, that.mRenameSuffix);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mNamePattern, mScanFilter, mRawDataFilter, mRawDataFilterMask,
+ mRenamePrefix, mRenameSuffix, mRenameBytesFrom, mRenameBytesTo,
+ mRenameBytesReverseOrder);
+ }
+
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(patternToString(getNamePattern()));
dest.writeParcelable(mScanFilter, flags);
+ dest.writeByteArray(mRawDataFilter);
+ dest.writeByteArray(mRawDataFilterMask);
+ dest.writeString(mRenamePrefix);
+ dest.writeString(mRenameSuffix);
+ dest.writeInt(mRenameBytesFrom);
+ dest.writeInt(mRenameBytesTo);
+ dest.writeBoolean(mRenameBytesReverseOrder);
}
@Override
@@ -174,13 +214,23 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
= new Creator<BluetoothLEDeviceFilter>() {
@Override
public BluetoothLEDeviceFilter createFromParcel(Parcel in) {
- return new BluetoothLEDeviceFilter.Builder()
+ Builder builder = new Builder()
.setNamePattern(patternFromString(in.readString()))
- .setScanFilter(in.readParcelable(null))
- .setRawDataFilter(in.readBlob(), in.readBlob())
- .setRename(in.readString(), in.readString(),
- in.readInt(), in.readInt(), in.readBoolean())
- .build();
+ .setScanFilter(in.readParcelable(null));
+ byte[] rawDataFilter = in.createByteArray();
+ byte[] rawDataFilterMask = in.createByteArray();
+ if (rawDataFilter != null) {
+ builder.setRawDataFilter(rawDataFilter, rawDataFilterMask);
+ }
+ String renamePrefix = in.readString();
+ String suffix = in.readString();
+ int bytesFrom = in.readInt();
+ int bytesTo = in.readInt();
+ boolean bytesReverseOrder = in.readBoolean();
+ if (renamePrefix != null) {
+ builder.setRename(renamePrefix, suffix, bytesFrom, bytesTo, bytesReverseOrder);
+ }
+ return builder.build();
}
@Override
@@ -240,12 +290,14 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
*/
@NonNull
public Builder setRawDataFilter(@NonNull byte[] rawDataFilter,
- @NonNull byte[] rawDataFilterMask) {
+ @Nullable byte[] rawDataFilterMask) {
checkNotUsed();
- checkArgument(rawDataFilter.length == rawDataFilterMask.length,
+ Preconditions.checkNotNull(rawDataFilter);
+ checkArgument(rawDataFilterMask == null ||
+ rawDataFilter.length == rawDataFilterMask.length,
"Mask and filter should be the same length");
- mRawDataFilter = Preconditions.checkNotNull(rawDataFilter);
- mRawDataFilterMask = Preconditions.checkNotNull(rawDataFilterMask);
+ mRawDataFilter = rawDataFilter;
+ mRawDataFilterMask = rawDataFilterMask;
return this;
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 78e3de47df06..7b38863c9cc6 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -17,6 +17,8 @@
package android.companion;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
@@ -24,7 +26,6 @@ import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -43,7 +44,7 @@ import java.util.List;
*/
public final class CompanionDeviceManager {
- private static final boolean DEBUG = false; //TODO
+ private static final boolean DEBUG = false;
private static final String LOG_TAG = "CompanionDeviceManager";
/**
@@ -129,10 +130,9 @@ public final class CompanionDeviceManager {
if (!checkFeaturePresent()) {
return;
}
-
- final Handler finalHandler = handler != null
- ? handler
- : new Handler(Looper.getMainLooper());
+ checkNotNull(request, "Request cannot be null");
+ checkNotNull(callback, "Callback cannot be null");
+ final Handler finalHandler = Handler.mainIfNull(handler);
try {
mService.associate(
request,
diff --git a/core/java/android/companion/WifiDeviceFilter.java b/core/java/android/companion/WifiDeviceFilter.java
index 1ab9ce11cb0f..b6e704c39998 100644
--- a/core/java/android/companion/WifiDeviceFilter.java
+++ b/core/java/android/companion/WifiDeviceFilter.java
@@ -29,6 +29,7 @@ import android.net.wifi.ScanResult;
import android.os.Parcel;
import android.provider.OneTimeUseBuilder;
+import java.util.Objects;
import java.util.regex.Pattern;
/**
@@ -75,6 +76,19 @@ public final class WifiDeviceFilter implements DeviceFilter<ScanResult> {
}
@Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ WifiDeviceFilter that = (WifiDeviceFilter) o;
+ return Objects.equals(mNamePattern, that.mNamePattern);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mNamePattern);
+ }
+
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(patternToString(getNamePattern()));
}
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index c28172c6347c..f1c2f342eb3e 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -150,7 +150,7 @@ public class ClipboardManager extends android.text.ClipboardManager {
public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener what) {
synchronized (mPrimaryClipChangedListeners) {
- if (mPrimaryClipChangedListeners.size() == 0) {
+ if (mPrimaryClipChangedListeners.isEmpty()) {
try {
mService.addPrimaryClipChangedListener(
mPrimaryClipChangedServiceListener, mContext.getOpPackageName());
@@ -165,7 +165,7 @@ public class ClipboardManager extends android.text.ClipboardManager {
public void removePrimaryClipChangedListener(OnPrimaryClipChangedListener what) {
synchronized (mPrimaryClipChangedListeners) {
mPrimaryClipChangedListeners.remove(what);
- if (mPrimaryClipChangedListeners.size() == 0) {
+ if (mPrimaryClipChangedListeners.isEmpty()) {
try {
mService.removePrimaryClipChangedListener(
mPrimaryClipChangedServiceListener);
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index fd1e24a48da5..8f3a31746266 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -508,14 +508,14 @@ public class ContentProviderOperation implements Parcelable {
/** Create a ContentProviderOperation from this {@link Builder}. */
public ContentProviderOperation build() {
if (mType == TYPE_UPDATE) {
- if ((mValues == null || mValues.size() == 0)
- && (mValuesBackReferences == null || mValuesBackReferences.size() == 0)) {
+ if ((mValues == null || mValues.isEmpty())
+ && (mValuesBackReferences == null || mValuesBackReferences.isEmpty())) {
throw new IllegalArgumentException("Empty values");
}
}
if (mType == TYPE_ASSERT) {
- if ((mValues == null || mValues.size() == 0)
- && (mValuesBackReferences == null || mValuesBackReferences.size() == 0)
+ if ((mValues == null || mValues.isEmpty())
+ && (mValuesBackReferences == null || mValuesBackReferences.isEmpty())
&& (mExpectedCount == null)) {
throw new IllegalArgumentException("Empty values");
}
diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java
index 3a87cb3e7a29..6f9379890a3a 100644
--- a/core/java/android/content/ContentValues.java
+++ b/core/java/android/content/ContentValues.java
@@ -204,6 +204,17 @@ public final class ContentValues implements Parcelable {
}
/**
+ * Indicates whether this collection is empty.
+ *
+ * @return true iff size == 0
+ * {@hide}
+ * TODO: consider exposing this new method publicly
+ */
+ public boolean isEmpty() {
+ return mValues.isEmpty();
+ }
+
+ /**
* Remove a single value.
*
* @param key the name of the value to remove
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3a8a4206e105..1803bbe24610 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2576,7 +2576,7 @@ public abstract class Context {
* {@link ComponentName} of the actual service that was started is
* returned; else if the service does not exist null is returned.
*
- * @throws SecurityException If the caller does not permission to access the service
+ * @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
* @throws IllegalStateException If the application is in a state where the service
* can not be started (such as not in the foreground in a state when services are allowed).
@@ -2588,11 +2588,47 @@ public abstract class Context {
public abstract ComponentName startService(Intent service);
/**
+ * Similar to {@link #startService(Intent)}, but with an implicit promise that the
+ * Service will call {@link android.app.Service#startForeground(int, Notification)
+ * startForeground(int, Notification)} once it begins running. The service is given
+ * an amount of time comparable to the ANR interval to do this, otherwise the system
+ * will automatically stop the service and declare the app ANR.
+ *
+ * <p>Unlike the ordinary {@link #startService(Intent)}, this method can be used
+ * at any time, regardless of whether the app hosting the service is in a foreground
+ * state.
+ *
+ * @param service Identifies the service to be started. The Intent must be
+ * fully explicit (supplying a component name). Additional values
+ * may be included in the Intent extras to supply arguments along with
+ * this specific start call.
+ *
+ * @return If the service is being started or is already running, the
+ * {@link ComponentName} of the actual service that was started is
+ * returned; else if the service does not exist null is returned.
+ *
+ * @throws SecurityException If the caller does not have permission to access the service
+ * or the service can not be found.
+ *
+ * @see #stopService
+ * @see android.app.Service#startForeground(int, Notification)
+ */
+ @Nullable
+ public abstract ComponentName startForegroundService(Intent service);
+
+ /**
+ * @hide like {@link #startForegroundService(Intent)} but for a specific user.
+ */
+ @Nullable
+ public abstract ComponentName startForegroundServiceAsUser(Intent service, UserHandle user);
+
+ /**
* Start a service directly into the "foreground service" state. Unlike {@link #startService},
* this method can be used from within background operations like broadcast receivers
* or scheduled jobs. The API entry point for this is in NotificationManager in order to
* preserve appropriate public package layering.
* @hide
+ * @deprecated STOPSHIP remove in favor of two-step startForegroundService() + startForeground()
*/
@Nullable
public abstract ComponentName startServiceInForeground(Intent service,
@@ -2620,7 +2656,7 @@ public abstract class Context {
* @return If there is a service matching the given Intent that is already
* running, then it is stopped and {@code true} is returned; else {@code false} is returned.
*
- * @throws SecurityException If the caller does not permission to access the service
+ * @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
* @throws IllegalStateException If the application is in a state where the service
* can not be started (such as not in the foreground in a state when services are allowed).
@@ -2638,7 +2674,9 @@ public abstract class Context {
/**
* @hide like {@link #startServiceInForeground(Intent, int, Notification)}
* but for a specific user.
+ * @deprecated STOPSHIP remove when trial API is turned off
*/
+ @Deprecated
@Nullable
public abstract ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user);
@@ -2685,7 +2723,7 @@ public abstract class Context {
* {@code false} is returned if the connection is not made so you will not
* receive the service object.
*
- * @throws SecurityException If the caller does not permission to access the service
+ * @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
*
* @see #unbindService
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6b0bbfaedc3e..75784a69c74c 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -644,7 +644,12 @@ public class ContextWrapper extends Context {
return mBase.startService(service);
}
- /** @hide */
+ @Override
+ public ComponentName startForegroundService(Intent service) {
+ return mBase.startForegroundService(service);
+ }
+
+ /** @hide STOPSHIP remove when trial API is turned down */
@Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
@@ -664,6 +669,12 @@ public class ContextWrapper extends Context {
/** @hide */
@Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ return mBase.startForegroundServiceAsUser(service, user);
+ }
+
+ /** @hide STOPSHIP removed when trial API is turned down */
+ @Override
public ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user) {
return mBase.startServiceInForegroundAsUser(service, id, notification, user);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index fb86791a509c..7890a9607932 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1532,6 +1532,19 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
/**
+ * Activity Action: Launch ephemeral settings.
+ *
+ * <p class="note">
+ * This is a protected intent that can only be sent by the system.
+ * </p>
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_EPHEMERAL_RESOLVER_SETTINGS
+ = "android.intent.action.EPHEMERAL_RESOLVER_SETTINGS";
+
+ /**
* Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} to install a
* package. Specifies the installer package name; this package will receive the
* {@link #ACTION_APP_ERROR} intent.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 59b022ded9bf..147df763fce2 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -630,4 +630,6 @@ interface IPackageManager {
boolean canRequestPackageInstalls(String packageName, int userId);
void deletePreloadsFileCache();
+
+ ComponentName getInstantAppResolverSettingsComponent();
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 71db5d311bd6..136c13b6f37d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -153,6 +153,7 @@ public abstract class PackageManager {
MATCH_UNINSTALLED_PACKAGES,
MATCH_SYSTEM_ONLY,
MATCH_DEBUG_TRIAGED_MISSING,
+ MATCH_DISABLED_COMPONENTS,
MATCH_DISABLED_UNTIL_USED_COMPONENTS,
MATCH_INSTANT,
GET_DISABLED_UNTIL_USED_COMPONENTS,
@@ -431,6 +432,7 @@ public abstract class PackageManager {
* This will not return information on any unbundled update to system components.
* @hide
*/
+ @SystemApi
public static final int MATCH_FACTORY_ONLY = 0x00200000;
/**
@@ -3730,6 +3732,7 @@ public abstract class PackageManager {
*
* @param flags Additional option flags. Use any combination of
* {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS}
* {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
* to modify the data returned.
*
@@ -3743,6 +3746,7 @@ public abstract class PackageManager {
*
* @see #GET_META_DATA
* @see #GET_SHARED_LIBRARY_FILES
+ * @see #MATCH_DISABLED_COMPONENTS
* @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
* @see #MATCH_SYSTEM_ONLY
* @see #MATCH_UNINSTALLED_PACKAGES
@@ -3757,6 +3761,7 @@ public abstract class PackageManager {
*
* @param flags Additional option flags. Use any combination of
* {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS}
* {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
* to modify the data returned.
* @param userId The user for whom the installed applications are to be listed
@@ -3772,6 +3777,7 @@ public abstract class PackageManager {
*
* @see #GET_META_DATA
* @see #GET_SHARED_LIBRARY_FILES
+ * @see #MATCH_DISABLED_COMPONENTS
* @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
* @see #MATCH_SYSTEM_ONLY
* @see #MATCH_UNINSTALLED_PACKAGES
@@ -6233,4 +6239,14 @@ public abstract class PackageManager {
* @see {@link android.provider.Settings#ACTION_MANAGE_EXTERNAL_SOURCES}
*/
public abstract boolean canRequestPackageInstalls();
+
+ /**
+ * Return the {@link ComponentName} of the activity providing Settings for the Instant App
+ * resolver.
+ *
+ * @see {@link android.content.intent#ACTION_EPHEMERAL_RESOLVER_SETTINGS}
+ * @hide
+ */
+ @SystemApi
+ public abstract ComponentName getInstantAppResolverSettingsComponent();
}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 6272822ac308..16d582efb730 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -172,6 +172,7 @@ public abstract class PackageManagerInternal {
* @param packageName The package name.
* @param userId The user for which to check.
* @return Whether was launched.
+ * @throws IllegalArgumentException if the package is not found
*/
public abstract boolean wasPackageEverLaunched(String packageName, int userId);
@@ -241,6 +242,7 @@ public abstract class PackageManagerInternal {
public abstract void grantEphemeralAccess(int userId, Intent intent,
int targetAppId, int ephemeralAppId);
+ public abstract boolean isInstantAppInstallerComponent(ComponentName component);
/**
* Prunes instant apps and state associated with uninstalled
* instant apps according to the current platform policy.
@@ -312,4 +314,17 @@ public abstract class PackageManagerInternal {
*/
public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId);
+
+ /**
+ * Track the creator of a new isolated uid.
+ * @param isolatedUid The newly created isolated uid.
+ * @param ownerUid The uid of the app that created the isolated process.
+ */
+ public abstract void addIsolatedUid(int isolatedUid, int ownerUid);
+
+ /**
+ * Track removal of an isolated uid.
+ * @param isolatedUid isolated uid that is no longer being used.
+ */
+ public abstract void removeIsolatedUid(int isolatedUid);
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1fafe6534077..d264e094ca3f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4400,8 +4400,12 @@ public class PackageParser {
defaultMaxAspectRatio = owner.applicationInfo.maxAspectRatio;
}
- aInfo.maxAspectRatio = Math.max(1.0f, sa.getFloat(
- R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio));
+ aInfo.maxAspectRatio = sa.getFloat(
+ R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio);
+ if (aInfo.maxAspectRatio < 1.0f && aInfo.maxAspectRatio != 0) {
+ // Ignore any value lesser than 1.0.
+ aInfo.maxAspectRatio = 0;
+ }
}
/**
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index 7a0158a8d9af..b992d29eb32f 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -242,6 +242,7 @@ import java.util.List;
* You can provide multiple intents for a single shortcut so that the last defined activity is launched
* with the other activities in the <a href="/guide/components/tasks-and-back-stack.html">back stack</a>.
* See {@link android.app.TaskStackBuilder} for details.
+ * <p><b>Note:</b> String resources may not be used within an {@code <intent>} element.
* </dd>
* <dt>{@code categories}</dt>
* <dd>Specify shortcut categories. Currently only
diff --git a/core/java/android/database/PageViewCursor.java b/core/java/android/database/PageViewCursor.java
index 44727a0d300e..4569a2765f51 100644
--- a/core/java/android/database/PageViewCursor.java
+++ b/core/java/android/database/PageViewCursor.java
@@ -15,6 +15,7 @@
*/
package android.database;
+import static com.android.internal.util.ArrayUtils.contains;
import static com.android.internal.util.Preconditions.checkArgument;
import android.annotation.Nullable;
@@ -25,7 +26,7 @@ import android.os.Bundle;
import android.util.Log;
import android.util.MathUtils;
-import com.android.internal.util.ArrayUtils;
+import java.util.Arrays;
/**
* Cursor wrapper that provides visibility into a subset of a wrapped cursor.
@@ -40,11 +41,12 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
/** An extra added to results that are auto-paged using the wrapper. */
public static final String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
+ private static final String[] EMPTY_ARGS = new String[0];
private static final String TAG = "PageViewCursor";
private static final boolean DEBUG = Build.IS_DEBUGGABLE;
private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
- private final int mOffset; // aka first index
+ private final int mOffset; // aka first index
private final int mCount;
private final Bundle mExtras;
@@ -55,12 +57,17 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
/**
* @see PageViewCursor#wrap(Cursor, Bundle)
*/
- public PageViewCursor(Cursor cursor, int offset, int limit) {
+ public PageViewCursor(Cursor cursor, Bundle queryArgs) {
super(cursor);
+ int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
+ int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE);
+
checkArgument(offset > -1);
checkArgument(limit > -1);
+ int count = mCursor.getCount();
+
mOffset = offset;
mExtras = new Bundle();
@@ -68,26 +75,47 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
if (extras != null) {
mExtras.putAll(extras);
}
- mExtras.putBoolean(EXTRA_AUTO_PAGED, true);
-
- // We need a mutable bundle so we can add QUERY_RESULT_SIZE.
- // Direct equality check is correct here. Bundle.EMPTY is a specific instance
- // of Bundle that is immutable by way of implementation.
- // mExtras = (extras == Bundle.EMPTY) ? new Bundle() : extras;
// When we're wrapping another cursor, it should not already be "paged".
- checkArgument(!mExtras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE));
+ checkArgument(!hasPagedResponseDetails(mExtras));
- int count = mCursor.getCount();
+ mExtras.putBoolean(EXTRA_AUTO_PAGED, true);
mExtras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, count);
+ // Ensure we retain any extra args supplied in cursor extras, and add
+ // offset and/or limit.
+ String[] existingArgs = mExtras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
+ existingArgs = existingArgs != null ? existingArgs : EMPTY_ARGS;
+
+ int size = existingArgs.length;
+
+ // copy the array with space for the extra query args we'll be adding.
+ String[] newArgs = Arrays.copyOf(existingArgs, size + 2);
+
+ if (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)) {
+ newArgs[size++] = ContentResolver.QUERY_ARG_OFFSET;
+ }
+ if (queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)) {
+ newArgs[size++] = ContentResolver.QUERY_ARG_LIMIT;
+ }
+
+ assert(size > existingArgs.length); // must add at least one arg.
+
+ // At this point there may be a null element at the end of
+ // the array because our pre-sizing didn't match the actualy
+ // number of args we added. So we trim.
+ if (size == newArgs.length - 1) {
+ newArgs = Arrays.copyOf(newArgs, size);
+ }
+ mExtras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, newArgs);
+
mCount = MathUtils.constrain(count - offset, 0, limit);
if (DEBUG) Log.d(TAG, "Wrapped cursor"
- + " offset: " + mOffset
- + ", limit: " + limit
- + ", delegate_size: " + count
- + ", paged_count: " + mCount);
+ + " offset: " + mOffset
+ + ", limit: " + limit
+ + ", delegate_size: " + count
+ + ", paged_count: " + mCount);
}
@Override
@@ -155,9 +183,9 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
public boolean moveToPosition(int position) {
if (position >= mCount) {
if (VERBOSE) Log.v(TAG, "Invalid Positon: " + position + " >= count: " + mCount
- + ". Moving to last record.");
+ + ". Moving to last record.");
mPos = mCount;
- super.moveToPosition(mOffset + mPos); // move into "after last" state.
+ super.moveToPosition(mOffset + mPos); // move into "after last" state.
return false;
}
@@ -198,15 +226,15 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
@Override
public boolean getWantsAllOnMoveCalls() {
- return false; // we want bulk cursor adapter to lift data into a CursorWindow.
+ return false; // we want bulk cursor adapter to lift data into a CursorWindow.
}
@Override
public CursorWindow getWindow() {
assert(mPos == -1 || mPos == 0);
if (mWindow == null) {
- mWindow = new CursorWindow("PageViewCursorWindow");
- fillWindow(0, mWindow);
+ mWindow = new CursorWindow("PageViewCursorWindow");
+ fillWindow(0, mWindow);
}
return mWindow;
@@ -224,17 +252,16 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
}
/**
- * Wraps the cursor such that it will honor paging args (if present), AND if the cursor
- * does not report paging size.
- *
- * <p>No-op if cursor already contains paging or is less than specified page size.
+ * Wraps the cursor such that it will honor paging args (if present), AND if the cursor does
+ * not report paging size.
+ * <p>
+ * No-op if cursor already contains paging or is less than specified page size.
*/
public static Cursor wrap(Cursor cursor, @Nullable Bundle queryArgs) {
- boolean hasPagingArgs =
- queryArgs != null
+ boolean hasPagingArgs = queryArgs != null
&& (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)
- || queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT));
+ || queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT));
if (!hasPagingArgs) {
if (VERBOSE) Log.v(TAG, "No-wrap: No paging args in request.");
@@ -253,25 +280,26 @@ public final class PageViewCursor extends CursorWrapper implements CrossProcessC
return cursor;
}
- return new PageViewCursor(
- cursor,
- queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0),
- queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE));
+ return new PageViewCursor(cursor, queryArgs);
}
/**
- * @return true if the extras contains information indicating the associated
- * cursor is paged.
+ * @return true if the extras contains information indicating the associated cursor is
+ * paged.
*/
private static boolean hasPagedResponseDetails(@Nullable Bundle extras) {
- if (extras != null && extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) {
+ if (extras == null) {
+ return false;
+ }
+
+ if (extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) {
return true;
}
String[] honoredArgs = extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
- if (honoredArgs != null && (
- ArrayUtils.contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)
- || ArrayUtils.contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) {
+ if (honoredArgs != null
+ && (contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)
+ || contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) {
return true;
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 8e178320d66d..fe849b8a99cf 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1449,7 +1449,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
sql.append('(');
Object[] bindArgs = null;
- int size = (initialValues != null && initialValues.size() > 0)
+ int size = (initialValues != null && !initialValues.isEmpty())
? initialValues.size() : 0;
if (size > 0) {
bindArgs = new Object[size];
@@ -1541,7 +1541,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
*/
public int updateWithOnConflict(String table, ContentValues values,
String whereClause, String[] whereArgs, int conflictAlgorithm) {
- if (values == null || values.size() == 0) {
+ if (values == null || values.isEmpty()) {
throw new IllegalArgumentException("Empty values");
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index dcd069d335e0..da771e48d85e 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -118,6 +118,11 @@ public abstract class CameraCaptureSession implements AutoCloseable {
* the Surface provided to prepare must not be used as a target of a CaptureRequest submitted
* to this session.</p>
*
+ * <p>Note that if 2 surfaces share the same stream via {@link
+ * OutputConfiguration#enableSurfaceSharing} and {@link OutputConfiguration#addSurface},
+ * prepare() only needs to be called on one surface, and {link
+ * StateCallback#onSurfacePrepared} will be triggered for both surfaces.</p>
+ *
* <p>{@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}
* devices cannot pre-allocate output buffers; for those devices,
* {@link StateCallback#onSurfacePrepared} will be immediately called, and no preallocation is
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index e3b97e82f6c8..e75b3758a31e 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -708,7 +708,8 @@ public class CameraDeviceImpl extends CameraDevice
synchronized(mInterfaceLock) {
int streamId = -1;
for (int i = 0; i < mConfiguredOutputs.size(); i++) {
- if (surface == mConfiguredOutputs.valueAt(i).getSurface()) {
+ final List<Surface> surfaces = mConfiguredOutputs.valueAt(i).getSurfaces();
+ if (surfaces.contains(surface)) {
streamId = mConfiguredOutputs.keyAt(i);
break;
}
@@ -2020,9 +2021,10 @@ public class CameraDeviceImpl extends CameraDevice
Log.w(TAG, "onPrepared invoked for unknown output Surface");
return;
}
- final Surface surface = output.getSurface();
-
- sessionCallback.onSurfacePrepared(surface);
+ final List<Surface> surfaces = output.getSurfaces();
+ for (Surface surface : surfaces) {
+ sessionCallback.onSurfacePrepared(surface);
+ }
}
@Override
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index dbe1394e20ee..00e047db98c0 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -1112,6 +1112,8 @@ public final class StreamConfigurationMap {
return ImageFormat.DEPTH_POINT_CLOUD;
case HAL_PIXEL_FORMAT_Y16:
return ImageFormat.DEPTH16;
+ case HAL_PIXEL_FORMAT_RAW16:
+ return ImageFormat.RAW_DEPTH;
case ImageFormat.JPEG:
throw new IllegalArgumentException(
"ImageFormat.JPEG is an unknown internal format");
@@ -1179,6 +1181,8 @@ public final class StreamConfigurationMap {
return HAL_PIXEL_FORMAT_BLOB;
case ImageFormat.DEPTH16:
return HAL_PIXEL_FORMAT_Y16;
+ case ImageFormat.RAW_DEPTH:
+ return HAL_PIXEL_FORMAT_RAW16;
default:
return format;
}
@@ -1220,6 +1224,7 @@ public final class StreamConfigurationMap {
return HAL_DATASPACE_V0_JFIF;
case ImageFormat.DEPTH_POINT_CLOUD:
case ImageFormat.DEPTH16:
+ case ImageFormat.RAW_DEPTH:
return HAL_DATASPACE_DEPTH;
default:
return HAL_DATASPACE_UNKNOWN;
@@ -1609,6 +1614,8 @@ public final class StreamConfigurationMap {
return "DEPTH16";
case ImageFormat.DEPTH_POINT_CLOUD:
return "DEPTH_POINT_CLOUD";
+ case ImageFormat.RAW_DEPTH:
+ return "RAW_DEPTH";
case ImageFormat.PRIVATE:
return "PRIVATE";
default:
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 14bb923767ed..0e59a2dfe6bb 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -196,6 +196,19 @@ public class RadioManager {
return mIsCaptureSupported;
}
+ /**
+ * {@code true} if the module supports background scanning. At the given time it may not
+ * be available though, see {@link RadioTuner#startBackgroundScan()}.
+ *
+ * @return {@code true} if background scanning is supported (not necessary available
+ * at a given time), {@code false} otherwise.
+ *
+ * @hide FutureFeature
+ */
+ public boolean isBackgroundScanningSupported() {
+ return false;
+ }
+
/** List of descriptors for all bands supported by this module.
* @return an array of {@link BandDescriptor}.
*/
@@ -1136,21 +1149,27 @@ public class RadioManager {
* {@link RadioTuner#getProgramInformation(RadioManager.ProgramInfo[])} */
public static class ProgramInfo implements Parcelable {
+ // sourced from hardware/interfaces/broadcastradio/1.1/types.hal
+ private final static int FLAG_LIVE = 1 << 0;
+ private final static int FLAG_MUTED = 1 << 1;
+
private final int mChannel;
private final int mSubChannel;
private final boolean mTuned;
private final boolean mStereo;
private final boolean mDigital;
+ private final int mFlags;
private final int mSignalStrength;
private final RadioMetadata mMetadata;
ProgramInfo(int channel, int subChannel, boolean tuned, boolean stereo,
- boolean digital, int signalStrength, RadioMetadata metadata) {
+ boolean digital, int signalStrength, RadioMetadata metadata, int flags) {
mChannel = channel;
mSubChannel = subChannel;
mTuned = tuned;
mStereo = stereo;
mDigital = digital;
+ mFlags = flags;
mSignalStrength = signalStrength;
mMetadata = metadata;
}
@@ -1186,6 +1205,30 @@ public class RadioManager {
public boolean isDigital() {
return mDigital;
}
+
+ /**
+ * {@code true} if the program is currently playing live stream.
+ * This may result in a slightly altered reception parameters,
+ * usually targetted at reduced latency.
+ *
+ * @hide FutureFeature
+ */
+ public boolean isLive() {
+ return (mFlags & FLAG_LIVE) != 0;
+ }
+
+ /**
+ * {@code true} if radio stream is not playing, ie. due to bad reception
+ * conditions or buffering. In this state volume knob MAY be disabled to
+ * prevent user increasing volume too much.
+ * It does NOT mean the user has muted audio.
+ *
+ * @hide FutureFeature
+ */
+ public boolean isMuted() {
+ return (mFlags & FLAG_MUTED) != 0;
+ }
+
/** Signal strength indicator from 0 (no signal) to 100 (excellent)
* @return the signal strength indication.
*/
@@ -1212,6 +1255,7 @@ public class RadioManager {
} else {
mMetadata = null;
}
+ mFlags = in.readInt();
}
public static final Parcelable.Creator<ProgramInfo> CREATOR
@@ -1239,6 +1283,7 @@ public class RadioManager {
dest.writeByte((byte)1);
mMetadata.writeToParcel(dest, flags);
}
+ dest.writeInt(mFlags);
}
@Override
@@ -1250,7 +1295,7 @@ public class RadioManager {
public String toString() {
return "ProgramInfo [mChannel=" + mChannel + ", mSubChannel=" + mSubChannel
+ ", mTuned=" + mTuned + ", mStereo=" + mStereo + ", mDigital=" + mDigital
- + ", mSignalStrength=" + mSignalStrength
+ + ", mFlags=" + mFlags + ", mSignalStrength=" + mSignalStrength
+ ((mMetadata == null) ? "" : (", mMetadata=" + mMetadata.toString()))
+ "]";
}
@@ -1264,6 +1309,7 @@ public class RadioManager {
result = prime * result + (mTuned ? 1 : 0);
result = prime * result + (mStereo ? 1 : 0);
result = prime * result + (mDigital ? 1 : 0);
+ result = prime * result + mFlags;
result = prime * result + mSignalStrength;
result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode());
return result;
@@ -1286,6 +1332,8 @@ public class RadioManager {
return false;
if (mDigital != other.isDigital())
return false;
+ if (mFlags != other.mFlags)
+ return false;
if (mSignalStrength != other.getSignalStrength())
return false;
if (mMetadata == null) {
diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java
index 89648931fd53..c0df0f386b09 100644
--- a/core/java/android/hardware/radio/RadioModule.java
+++ b/core/java/android/hardware/radio/RadioModule.java
@@ -79,8 +79,14 @@ public class RadioModule extends RadioTuner {
public native int getProgramInformation(RadioManager.ProgramInfo[] info);
+ public native boolean startBackgroundScan();
+
public native @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
+ public native boolean isAnalogForced();
+
+ public native void setAnalogForced(boolean isForced);
+
public native boolean isAntennaConnected();
public native boolean hasControl();
diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index c8034eb94992..6e1232d84481 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -212,6 +212,23 @@ public abstract class RadioTuner {
public abstract int getProgramInformation(RadioManager.ProgramInfo[] info);
/**
+ * Initiates a background scan to update internally cached program list.
+ *
+ * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot.
+ *
+ * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will
+ * be called if the return value of this call was {@code true}. As result of this call
+ * programListChanged may be triggered (if the scanned list differs).
+ *
+ * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature
+ * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device
+ * or permanently if the feature is not supported
+ * (see ModuleProperties#isBackgroundScanningSupported()).
+ * @hide FutureFeature
+ */
+ public abstract boolean startBackgroundScan();
+
+ /**
* Get the list of discovered radio stations.
*
* To get the full list, set filter to null or empty string. Otherwise, client application
@@ -219,13 +236,40 @@ public abstract class RadioTuner {
*
* @param filter vendor-specific selector for radio stations.
* @return a list of radio stations.
- * @throws IllegalStateException if the scan is in progress or has not been started.
+ * @throws IllegalStateException if the scan is in progress or has not been started,
+ * startBackgroundScan() call may fix it.
* @throws IllegalArgumentException if the filter argument is not valid.
* @hide FutureFeature
*/
public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
/**
+ * Checks, if the analog playback is forced, see setAnalogForced.
+ *
+ * @throws IllegalStateException if the switch is not supported at current
+ * configuration.
+ * @return {@code true} if analog is forced, {@code false} otherwise.
+ * @hide FutureFeature
+ */
+ public abstract boolean isAnalogForced();
+
+ /**
+ * Forces the analog playback for the supporting radio technology.
+ *
+ * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+ * this option. This is purely user choice, ie. does not reflect digital-
+ * analog handover managed from the HAL implementation side.
+ *
+ * Some radio technologies may not support this, ie. DAB.
+ *
+ * @param isForced {@code true} to force analog, {@code false} for a default behaviour.
+ * @throws IllegalStateException if the switch is not supported at current
+ * configuration.
+ * @hide FutureFeature
+ */
+ public abstract void setAnalogForced(boolean isForced);
+
+ /**
* Get current antenna connection state for current configuration.
* Only valid if a configuration has been applied.
* @return {@code true} if the antenna is connected, {@code false} otherwise.
@@ -317,6 +361,32 @@ public abstract class RadioTuner {
* with control set to {@code true}.
*/
public void onControlChanged(boolean control) {}
+
+ /**
+ * onBackgroundScanAvailabilityChange() is called when background scan
+ * feature becomes available or not.
+ *
+ * @param isAvailable true, if the tuner turned temporarily background-
+ * capable, false in the other case.
+ * @hide FutureFeature
+ */
+ public void onBackgroundScanAvailabilityChange(boolean isAvailable) {}
+
+ /**
+ * Called when a background scan completes successfully.
+ *
+ * @hide FutureFeature
+ */
+ public void onBackgroundScanComplete() {}
+
+ /**
+ * Called when available program list changed.
+ *
+ * Use getProgramList() to get the actual list.
+ *
+ * @hide FutureFeature
+ */
+ public void onProgramListChanged() {}
}
}
diff --git a/core/java/android/metrics/LogMaker.java b/core/java/android/metrics/LogMaker.java
index 60b27b47960f..04482210c088 100644
--- a/core/java/android/metrics/LogMaker.java
+++ b/core/java/android/metrics/LogMaker.java
@@ -16,6 +16,7 @@
package android.metrics;
import android.annotation.SystemApi;
+import android.content.ComponentName;
import android.util.Log;
import android.util.SparseArray;
@@ -118,6 +119,16 @@ public class LogMaker {
return this;
}
+ /**
+ * @param component to replace the existing setting.
+ * @hide
+ */
+ public LogMaker setComponentName(ComponentName component) {
+ entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME, component.getPackageName());
+ entries.put(MetricsEvent.FIELD_CLASS_NAME, component.getClassName());
+ return this;
+ }
+
/** Remove the package name property. */
public LogMaker clearPackageName() {
entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME);
diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl
new file mode 100644
index 000000000000..b8737fef72e2
--- /dev/null
+++ b/core/java/android/net/IIpSecService.aidl
@@ -0,0 +1,24 @@
+/*
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.net;
+
+/**
+ * @hide
+ */
+interface IIpSecService
+{
+}
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 2c544e9b9bfe..83f4cc97b8fa 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -18,8 +18,6 @@ package android.net;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
import android.util.AndroidException;
import dalvik.system.CloseGuard;
@@ -79,12 +77,11 @@ public final class IpSecManager {
}
}
- private final Context mContext;
- private final INetworkManagementService mService;
+ private final IIpSecService mService;
public static final class SecurityParameterIndex implements AutoCloseable {
- private final Context mContext;
- private final InetAddress mDestinationAddress;
+ private final IIpSecService mService;
+ private final InetAddress mRemoteAddress;
private final CloseGuard mCloseGuard = CloseGuard.get();
private int mSpi;
@@ -93,10 +90,11 @@ public final class IpSecManager {
return mSpi;
}
- private SecurityParameterIndex(Context context, InetAddress destinationAddress, int spi)
+ private SecurityParameterIndex(
+ IIpSecService service, int direction, InetAddress remoteAddress, int spi)
throws ResourceUnavailableException, SpiUnavailableException {
- mContext = context;
- mDestinationAddress = destinationAddress;
+ mService = service;
+ mRemoteAddress = remoteAddress;
mSpi = spi;
mCloseGuard.open("open");
}
@@ -104,13 +102,9 @@ public final class IpSecManager {
/**
* Release an SPI that was previously reserved.
*
- * <p>Release an SPI for use by other users in the system. This will fail if the SPI is
- * currently in use by an IpSecTransform.
- *
- * @param destinationAddress SPIs must be unique for each combination of SPI and destination
- * address. Thus, the destinationAddress to which the SPI will communicate must be
- * supplied.
- * @param spi the previously reserved SPI to be freed.
+ * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is
+ * applied to an IpSecTransform, it will become unusable for future transforms but should
+ * still be closed to ensure system resources are released.
*/
@Override
public void close() {
@@ -136,13 +130,13 @@ public final class IpSecManager {
public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
/**
- * Reserve an SPI for traffic bound towards the specified destination address.
+ * Reserve an SPI for traffic bound towards the specified remote address.
*
* <p>If successful, this SPI is guaranteed available until released by a call to {@link
* SecurityParameterIndex#close()}.
*
- * @param destinationAddress SPIs must be unique for each combination of SPI and destination
- * address.
+ * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
+ * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
* @param requestedSpi the requested SPI, or '0' to allocate a random SPI.
* @return the reserved SecurityParameterIndex
* @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
@@ -150,9 +144,9 @@ public final class IpSecManager {
* @throws SpiUnavailableException indicating that a particular SPI cannot be reserved
*/
public SecurityParameterIndex reserveSecurityParameterIndex(
- InetAddress destinationAddress, int requestedSpi)
+ int direction, InetAddress remoteAddress, int requestedSpi)
throws SpiUnavailableException, ResourceUnavailableException {
- return new SecurityParameterIndex(mContext, destinationAddress, requestedSpi);
+ return new SecurityParameterIndex(mService, direction, remoteAddress, requestedSpi);
}
/**
@@ -260,19 +254,19 @@ public final class IpSecManager {
*/
public static final class UdpEncapsulationSocket implements AutoCloseable {
private final FileDescriptor mFd;
- private final Context mContext;
+ private final IIpSecService mService;
private final CloseGuard mCloseGuard = CloseGuard.get();
- private UdpEncapsulationSocket(Context context, int port)
+ private UdpEncapsulationSocket(IIpSecService service, int port)
throws ResourceUnavailableException {
- mContext = context;
+ mService = service;
mCloseGuard.open("constructor");
// TODO: go down to the kernel and get a socket on the specified
mFd = new FileDescriptor();
}
- private UdpEncapsulationSocket(Context context) throws ResourceUnavailableException {
- mContext = context;
+ private UdpEncapsulationSocket(IIpSecService service) throws ResourceUnavailableException {
+ mService = service;
mCloseGuard.open("constructor");
// TODO: go get a random socket on a random port
mFd = new FileDescriptor();
@@ -339,7 +333,7 @@ public final class IpSecManager {
public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
throws IOException, ResourceUnavailableException {
// Temporary code
- return new UdpEncapsulationSocket(mContext, port);
+ return new UdpEncapsulationSocket(mService, port);
}
/**
@@ -363,7 +357,7 @@ public final class IpSecManager {
public UdpEncapsulationSocket openUdpEncapsulationSocket()
throws IOException, ResourceUnavailableException {
// Temporary code
- return new UdpEncapsulationSocket(mContext);
+ return new UdpEncapsulationSocket(mService);
}
/**
@@ -372,8 +366,7 @@ public final class IpSecManager {
* @param context the application context for this manager
* @hide
*/
- public IpSecManager(Context context, INetworkManagementService service) {
- mContext = checkNotNull(context, "missing context");
+ public IpSecManager(IIpSecService service) {
mService = checkNotNull(service, "missing service");
}
}
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index d6dd28bec390..5c0bbe6a1437 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -307,7 +307,7 @@ public final class IpSecTransform implements AutoCloseable {
* <p>Care should be chosen when selecting an SPI to ensure that is is as unique as
* possible. Random number generation is a reasonable approach to selecting an SPI. For
* outbound SPIs, they must be reserved by calling {@link
- * IpSecManager#reserveSecurityParameterIndex(InetAddress, int)}. Otherwise, Transforms will
+ * IpSecManager#reserveSecurityParameterIndex(int, InetAddress, int)}. Otherwise, Transforms will
* fail to build.
*
* <p>Unless an SPI is set for a given direction, traffic in that direction will be
@@ -329,7 +329,7 @@ public final class IpSecTransform implements AutoCloseable {
* <p>Care should be chosen when selecting an SPI to ensure that is is as unique as
* possible. Random number generation is a reasonable approach to selecting an SPI. For
* outbound SPIs, they must be reserved by calling {@link
- * IpSecManager#reserveSecurityParameterIndex(InetAddress, int)}. Otherwise, Transforms will
+ * IpSecManager#reserveSecurityParameterIndex(int, InetAddress, int)}. Otherwise, Transforms will
* fail to activate.
*
* <p>Unless an SPI is set for a given direction, traffic in that direction will be
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 70ecf89dc155..29483cd98bd1 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -120,6 +120,14 @@ public class NetworkScoreManager {
"android.net.wifi.use_open_wifi_package";
/**
+ * Meta-data specified on a {@link NetworkRecommendationProvider} that specifies the
+ * {@link android.app.NotificationChannel} ID used to post open network notifications.
+ * @hide
+ */
+ public static final String NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA =
+ "android.net.wifi.notification_channel_id_network_available";
+
+ /**
* Broadcast action: the active scorer has been changed. Scorer apps may listen to this to
* perform initialization once selected as the active scorer, or clean up unneeded resources
* if another scorer has been selected. This is an explicit broadcast only sent to the
diff --git a/core/java/android/net/NetworkScorerAppData.java b/core/java/android/net/NetworkScorerAppData.java
index 5bf1e103a2de..1734b347ab9c 100644
--- a/core/java/android/net/NetworkScorerAppData.java
+++ b/core/java/android/net/NetworkScorerAppData.java
@@ -23,13 +23,20 @@ public final class NetworkScorerAppData implements Parcelable {
* wifi networks automatically" feature.
*/
private final ComponentName mEnableUseOpenWifiActivity;
+ /**
+ * The {@link android.app.NotificationChannel} ID used by {@link #mRecommendationService} to
+ * post open network notifications.
+ */
+ private final String mNetworkAvailableNotificationChannelId;
public NetworkScorerAppData(int packageUid, ComponentName recommendationServiceComp,
- String recommendationServiceLabel, ComponentName enableUseOpenWifiActivity) {
+ String recommendationServiceLabel, ComponentName enableUseOpenWifiActivity,
+ String networkAvailableNotificationChannelId) {
this.packageUid = packageUid;
this.mRecommendationService = recommendationServiceComp;
this.mRecommendationServiceLabel = recommendationServiceLabel;
this.mEnableUseOpenWifiActivity = enableUseOpenWifiActivity;
+ this.mNetworkAvailableNotificationChannelId = networkAvailableNotificationChannelId;
}
protected NetworkScorerAppData(Parcel in) {
@@ -37,6 +44,7 @@ public final class NetworkScorerAppData implements Parcelable {
mRecommendationService = ComponentName.readFromParcel(in);
mRecommendationServiceLabel = in.readString();
mEnableUseOpenWifiActivity = ComponentName.readFromParcel(in);
+ mNetworkAvailableNotificationChannelId = in.readString();
}
@Override
@@ -45,6 +53,7 @@ public final class NetworkScorerAppData implements Parcelable {
ComponentName.writeToParcel(mRecommendationService, dest);
dest.writeString(mRecommendationServiceLabel);
ComponentName.writeToParcel(mEnableUseOpenWifiActivity, dest);
+ dest.writeString(mNetworkAvailableNotificationChannelId);
}
@Override
@@ -83,6 +92,11 @@ public final class NetworkScorerAppData implements Parcelable {
return mRecommendationServiceLabel;
}
+ @Nullable
+ public String getNetworkAvailableNotificationChannelId() {
+ return mNetworkAvailableNotificationChannelId;
+ }
+
@Override
public String toString() {
return "NetworkScorerAppData{" +
@@ -90,6 +104,8 @@ public final class NetworkScorerAppData implements Parcelable {
", mRecommendationService=" + mRecommendationService +
", mRecommendationServiceLabel=" + mRecommendationServiceLabel +
", mEnableUseOpenWifiActivity=" + mEnableUseOpenWifiActivity +
+ ", mNetworkAvailableNotificationChannelId=" +
+ mNetworkAvailableNotificationChannelId +
'}';
}
@@ -101,12 +117,14 @@ public final class NetworkScorerAppData implements Parcelable {
return packageUid == that.packageUid &&
Objects.equals(mRecommendationService, that.mRecommendationService) &&
Objects.equals(mRecommendationServiceLabel, that.mRecommendationServiceLabel) &&
- Objects.equals(mEnableUseOpenWifiActivity, that.mEnableUseOpenWifiActivity);
+ Objects.equals(mEnableUseOpenWifiActivity, that.mEnableUseOpenWifiActivity) &&
+ Objects.equals(mNetworkAvailableNotificationChannelId,
+ that.mNetworkAvailableNotificationChannelId);
}
@Override
public int hashCode() {
return Objects.hash(packageUid, mRecommendationService, mRecommendationServiceLabel,
- mEnableUseOpenWifiActivity);
+ mEnableUseOpenWifiActivity, mNetworkAvailableNotificationChannelId);
}
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 3c7c962eaa12..8678d95db17d 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -16,6 +16,8 @@
package android.os;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.util.Log;
import android.util.Printer;
@@ -69,6 +71,7 @@ public class Handler {
*/
private static final boolean FIND_POTENTIAL_LEAKS = false;
private static final String TAG = "Handler";
+ private static Handler MAIN_THREAD_HANDLER = null;
/**
* Callback interface you can use when instantiating a Handler to avoid
@@ -231,6 +234,21 @@ public class Handler {
mAsynchronous = async;
}
+ /** @hide */
+ @NonNull
+ public static Handler getMain() {
+ if (MAIN_THREAD_HANDLER == null) {
+ MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper());
+ }
+ return MAIN_THREAD_HANDLER;
+ }
+
+ /** @hide */
+ @NonNull
+ public static Handler mainIfNull(@Nullable Handler handler) {
+ return handler == null ? getMain() : handler;
+ }
+
/** {@hide} */
public String getTraceName(Message message) {
final StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/os/HidlSupport.java b/core/java/android/os/HidlSupport.java
new file mode 100644
index 000000000000..7dec4d724f15
--- /dev/null
+++ b/core/java/android/os/HidlSupport.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.IntStream;
+
+/** @hide */
+public class HidlSupport {
+ /**
+ * Similar to Objects.deepEquals, but also take care of lists.
+ * Two objects of HIDL types are considered equal if:
+ * 1. Both null
+ * 2. Both non-null, and of the same class, and:
+ * 2.1 Both are primitive arrays / enum arrays, elements are equal using == check
+ * 2.2 Both are object arrays, elements are checked recursively
+ * 2.3 Both are Lists, elements are checked recursively
+ * 2.4 (If both are collections other than lists or maps, throw an error)
+ * 2.5 lft.equals(rgt) returns true
+ */
+ public static boolean deepEquals(Object lft, Object rgt) {
+ if (lft == rgt) {
+ return true;
+ }
+ if (lft == null || rgt == null) {
+ return false;
+ }
+
+ Class<?> lftClazz = lft.getClass();
+ Class<?> rgtClazz = rgt.getClass();
+ if (lftClazz != rgtClazz) {
+ return false;
+ }
+
+ if (lftClazz.isArray()) {
+ Class<?> lftElementType = lftClazz.getComponentType();
+ if (lftElementType != rgtClazz.getComponentType()) {
+ return false;
+ }
+
+ if (lftElementType.isPrimitive()) {
+ return Objects.deepEquals(lft, rgt);
+ }
+
+ Object[] lftArray = (Object[])lft;
+ Object[] rgtArray = (Object[])rgt;
+ return (lftArray.length == rgtArray.length) &&
+ IntStream.range(0, lftArray.length).allMatch(
+ i -> deepEquals(lftArray[i], rgtArray[i]));
+ }
+
+ if (lft instanceof List<?>) {
+ List<Object> lftList = (List<Object>)lft;
+ List<Object> rgtList = (List<Object>)rgt;
+ if (lftList.size() != rgtList.size()) {
+ return false;
+ }
+
+ Iterator<Object> lftIter = lftList.iterator();
+ return rgtList.stream()
+ .allMatch(rgtElement -> deepEquals(lftIter.next(), rgtElement));
+ }
+
+ throwErrorIfUnsupportedType(lft);
+
+ return lft.equals(rgt);
+ }
+
+ /**
+ * Similar to Arrays.deepHashCode, but also take care of lists.
+ */
+ public static int deepHashCode(Object o) {
+ if (o == null) {
+ return 0;
+ }
+ Class<?> clazz = o.getClass();
+ if (clazz.isArray()) {
+ Class<?> elementType = clazz.getComponentType();
+ if (elementType.isPrimitive()) {
+ return primitiveArrayHashCode(o);
+ }
+ return Arrays.hashCode(Arrays.stream((Object[])o)
+ .mapToInt(element -> deepHashCode(element))
+ .toArray());
+ }
+
+ if (o instanceof List<?>) {
+ return Arrays.hashCode(((List<Object>)o).stream()
+ .mapToInt(element -> deepHashCode(element))
+ .toArray());
+ }
+
+ throwErrorIfUnsupportedType(o);
+
+ return o.hashCode();
+ }
+
+ private static void throwErrorIfUnsupportedType(Object o) {
+ if (o instanceof Collection<?> && !(o instanceof List<?>)) {
+ throw new UnsupportedOperationException(
+ "Cannot check equality on collections other than lists: " +
+ o.getClass().getName());
+ }
+
+ if (o instanceof Map<?, ?>) {
+ throw new UnsupportedOperationException(
+ "Cannot check equality on maps");
+ }
+ }
+
+ private static int primitiveArrayHashCode(Object o) {
+ Class<?> elementType = o.getClass().getComponentType();
+ if (elementType == boolean.class) {
+ return Arrays.hashCode(((boolean[])o));
+ }
+ if (elementType == byte.class) {
+ return Arrays.hashCode(((byte[])o));
+ }
+ if (elementType == char.class) {
+ return Arrays.hashCode(((char[])o));
+ }
+ if (elementType == double.class) {
+ return Arrays.hashCode(((double[])o));
+ }
+ if (elementType == float.class) {
+ return Arrays.hashCode(((float[])o));
+ }
+ if (elementType == int.class) {
+ return Arrays.hashCode(((int[])o));
+ }
+ if (elementType == long.class) {
+ return Arrays.hashCode(((long[])o));
+ }
+ if (elementType == short.class) {
+ return Arrays.hashCode(((short[])o));
+ }
+ // Should not reach here.
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 63d3e7ad2135..44dbcfb09582 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.os.LooperProto;
import android.util.Log;
import android.util.Printer;
+import android.util.Slog;
import android.util.proto.ProtoOutputStream;
/**
@@ -76,6 +77,9 @@ public final class Looper {
private Printer mLogging;
private long mTraceTag;
+ /* If set, the looper will show a warning log if a message dispatch takes longer than time. */
+ private long mSlowDispatchThresholdMs;
+
/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
@@ -148,17 +152,30 @@ public final class Looper {
msg.callback + ": " + msg.what);
}
+ final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
+
final long traceTag = me.mTraceTag;
if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
+ final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
+ final long end;
try {
msg.target.dispatchMessage(msg);
+ end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
+ if (slowDispatchThresholdMs > 0) {
+ final long time = end - start;
+ if (time > slowDispatchThresholdMs) {
+ Slog.w(TAG, "Dispatch took " + time + "ms on "
+ + Thread.currentThread().getName() + ", h=" +
+ msg.target + " cb=" + msg.callback + " msg=" + msg.what);
+ }
+ }
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
@@ -226,6 +243,11 @@ public final class Looper {
mTraceTag = traceTag;
}
+ /** {@hide} */
+ public void setSlowDispatchThresholdMs(long slowDispatchThresholdMs) {
+ mSlowDispatchThresholdMs = slowDispatchThresholdMs;
+ }
+
/**
* Quits the looper.
* <p>
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index ef5bc5cf9075..5f66abd58d8b 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -483,7 +483,7 @@ public class RecoverySystem {
}
final String filenameArg = "--update_package=" + filename + "\n";
- final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n";
+ final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() + "\n";
final String securityArg = "--security\n";
String command = filenameArg + localeArg;
@@ -531,7 +531,7 @@ public class RecoverySystem {
}
final String filenameArg = "--update_package=" + filename + "\n";
- final String localeArg = "--locale=" + Locale.getDefault().toString() + "\n";
+ final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() + "\n";
final String securityArg = "--security\n";
String command = filenameArg + localeArg;
@@ -647,7 +647,7 @@ public class RecoverySystem {
reasonArg = "--reason=" + sanitizeArg(reason);
}
- final String localeArg = "--locale=" + Locale.getDefault().toString();
+ final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ;
bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
}
@@ -678,7 +678,7 @@ public class RecoverySystem {
reasonArg = "--reason=" + sanitizeArg(reason);
}
- final String localeArg = "--locale=" + Locale.getDefault().toString();
+ final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ;
bootCommand(context, "--wipe_cache", reasonArg, localeArg);
}
@@ -703,7 +703,7 @@ public class RecoverySystem {
final String filename = packageFile.getCanonicalPath();
final String filenameArg = "--wipe_package=" + filename;
- final String localeArg = "--locale=" + Locale.getDefault().toString();
+ final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ;
bootCommand(context, "--wipe_ab", filenameArg, reasonArg, localeArg);
}
@@ -741,6 +741,10 @@ public class RecoverySystem {
int timeTotal = -1;
int uncryptTime = -1;
int sourceVersion = -1;
+ int temperature_start = -1;
+ int temperature_end = -1;
+ int temperature_max = -1;
+
while ((line = in.readLine()) != null) {
// Here is an example of lines in last_install:
// ...
@@ -785,6 +789,12 @@ public class RecoverySystem {
} else if (line.startsWith("bytes_stashed")) {
bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled :
bytesStashedInMiB + scaled;
+ } else if (line.startsWith("temperature_start")) {
+ temperature_start = scaled;
+ } else if (line.startsWith("temperature_end")) {
+ temperature_end = scaled;
+ } else if (line.startsWith("temperature_max")) {
+ temperature_max = scaled;
}
}
@@ -804,6 +814,15 @@ public class RecoverySystem {
if (bytesStashedInMiB != -1) {
MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB);
}
+ if (temperature_start != -1) {
+ MetricsLogger.histogram(context, "ota_temperature_start", temperature_start);
+ }
+ if (temperature_end != -1) {
+ MetricsLogger.histogram(context, "ota_temperature_end", temperature_end);
+ }
+ if (temperature_max != -1) {
+ MetricsLogger.histogram(context, "ota_temperature_max", temperature_max);
+ }
} catch (IOException e) {
Log.e(TAG, "Failed to read lines in last_install", e);
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index b3366d883fc6..8208438dc62a 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -487,11 +487,11 @@ public class ZygoteProcess {
* Instructs the zygote to pre-load the classes and native libraries at the given paths
* for the specified abi. Not all zygotes support this function.
*/
- public void preloadPackageForAbi(String packagePath, String libsPath, String abi)
- throws ZygoteStartFailedEx, IOException {
+ public void preloadPackageForAbi(String packagePath, String libsPath, String cacheKey,
+ String abi) throws ZygoteStartFailedEx, IOException {
synchronized(mLock) {
ZygoteState state = openZygoteSocketIfNeeded(abi);
- state.writer.write("3");
+ state.writer.write("4");
state.writer.newLine();
state.writer.write("--preload-package");
@@ -503,6 +503,9 @@ public class ZygoteProcess {
state.writer.write(libsPath);
state.writer.newLine();
+ state.writer.write(cacheKey);
+ state.writer.newLine();
+
state.writer.flush();
}
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 7e1b5abf8112..e5d73e04bda6 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -59,6 +59,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.AppFuseMount;
import com.android.internal.os.FuseAppLoop;
+import com.android.internal.os.FuseAppLoop.UnmountedException;
+import com.android.internal.os.FuseUnavailableMountException;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
@@ -82,6 +84,7 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
+import libcore.io.IoUtils;
/**
* StorageManager is the interface to the systems storage service. The storage
@@ -1390,53 +1393,52 @@ public class StorageManager {
/** {@hide} */
@VisibleForTesting
public @NonNull ParcelFileDescriptor openProxyFileDescriptor(
- int mode, ProxyFileDescriptorCallback callback, ThreadFactory factory)
+ int mode, ProxyFileDescriptorCallback callback, Handler handler, ThreadFactory factory)
throws IOException {
MetricsLogger.count(mContext, "storage_open_proxy_file_descriptor", 1);
// Retry is needed because the mount point mFuseAppLoop is using may be unmounted before
// invoking StorageManagerService#openProxyFileDescriptor. In this case, we need to re-mount
// the bridge by calling mountProxyFileDescriptorBridge.
- int retry = 3;
- while (retry-- > 0) {
+ while (true) {
try {
synchronized (mFuseAppLoopLock) {
+ boolean newlyCreated = false;
if (mFuseAppLoop == null) {
final AppFuseMount mount = mStorageManager.mountProxyFileDescriptorBridge();
if (mount == null) {
- Log.e(TAG, "Failed to open proxy file bridge.");
- throw new IOException("Failed to open proxy file bridge.");
+ throw new IOException("Failed to mount proxy bridge");
}
- mFuseAppLoop = FuseAppLoop.open(mount.mountPointId, mount.fd, factory);
+ mFuseAppLoop = new FuseAppLoop(mount.mountPointId, mount.fd, factory);
+ newlyCreated = true;
+ }
+ if (handler == null) {
+ handler = new Handler(Looper.getMainLooper());
}
-
try {
- final int fileId = mFuseAppLoop.registerCallback(callback);
- final ParcelFileDescriptor pfd =
- mStorageManager.openProxyFileDescriptor(
- mFuseAppLoop.getMountPointId(), fileId, mode);
- if (pfd != null) {
- return pfd;
+ final int fileId = mFuseAppLoop.registerCallback(callback, handler);
+ final ParcelFileDescriptor pfd = mStorageManager.openProxyFileDescriptor(
+ mFuseAppLoop.getMountPointId(), fileId, mode);
+ if (pfd == null) {
+ mFuseAppLoop.unregisterCallback(fileId);
+ throw new FuseUnavailableMountException(
+ mFuseAppLoop.getMountPointId());
+ }
+ return pfd;
+ } catch (FuseUnavailableMountException exception) {
+ // The bridge is being unmounted. Tried to recreate it unless the bridge was
+ // just created.
+ if (newlyCreated) {
+ throw new IOException(exception);
}
- // Probably the bridge is being unmounted but mFuseAppLoop has not been
- // noticed it yet.
- mFuseAppLoop.unregisterCallback(fileId);
- } catch (FuseAppLoop.UnmountedException error) {
- Log.d(TAG, "mFuseAppLoop has been already unmounted.");
mFuseAppLoop = null;
continue;
}
}
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- break;
- }
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ // Cannot recover from remote exception.
+ throw new IOException(e);
}
}
-
- throw new IOException("Failed to mount bridge.");
}
/**
@@ -1448,16 +1450,37 @@ public class StorageManager {
* {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, or
* {@link ParcelFileDescriptor#MODE_READ_WRITE}
* @param callback Callback to process file operation requests issued on returned file
- * descriptor. The callback is invoked on a thread managed by the framework.
+ * descriptor.
* @return Seekable ParcelFileDescriptor.
* @throws IOException
*/
public @NonNull ParcelFileDescriptor openProxyFileDescriptor(
int mode, ProxyFileDescriptorCallback callback)
throws IOException {
- return openProxyFileDescriptor(mode, callback, null);
+ return openProxyFileDescriptor(mode, callback, null, null);
}
+ /**
+ * Opens seekable ParcelFileDescriptor that routes file operation requests to
+ * ProxyFileDescriptorCallback.
+ *
+ * @param mode The desired access mode, must be one of
+ * {@link ParcelFileDescriptor#MODE_READ_ONLY},
+ * {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, or
+ * {@link ParcelFileDescriptor#MODE_READ_WRITE}
+ * @param callback Callback to process file operation requests issued on returned file
+ * descriptor.
+ * @param handler Handler that invokes callback methods.
+ * @return Seekable ParcelFileDescriptor.
+ * @throws IOException
+ */
+ public @NonNull ParcelFileDescriptor openProxyFileDescriptor(
+ int mode, ProxyFileDescriptorCallback callback, Handler handler)
+ throws IOException {
+ return openProxyFileDescriptor(mode, callback, handler, null);
+ }
+
+
/** {@hide} */
@VisibleForTesting
public int getProxyFileDescriptorMountPointId() {
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 4d14277be9c1..d3adce73582e 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -83,6 +83,7 @@ import java.util.Set;
* @attr ref android.R.styleable#Preference_shouldDisableView
* @attr ref android.R.styleable#Preference_recycleEnabled
* @attr ref android.R.styleable#Preference_singleLineTitle
+ * @attr ref android.R.styleable#Preference_iconSpaceReserved
*/
public class Preference implements Comparable<Preference> {
/**
@@ -135,6 +136,7 @@ public class Preference implements Comparable<Preference> {
private boolean mParentDependencyMet = true;
private boolean mRecycleEnabled = true;
private boolean mSingleLineTitle = true;
+ private boolean mIconSpaceReserved;
/**
* @see #setShouldDisableView(boolean)
@@ -302,7 +304,11 @@ public class Preference implements Comparable<Preference> {
case com.android.internal.R.styleable.Preference_singleLineTitle:
mSingleLineTitle = a.getBoolean(attr, mSingleLineTitle);
break;
- }
+
+ case com.android.internal.R.styleable.Preference_iconSpaceReserved:
+ mIconSpaceReserved = a.getBoolean(attr, mIconSpaceReserved);
+ break;
+ }
}
a.recycle();
}
@@ -631,7 +637,11 @@ public class Preference implements Comparable<Preference> {
imageView.setImageDrawable(mIcon);
}
}
- imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
+ if (mIcon != null) {
+ imageView.setVisibility(View.VISIBLE);
+ } else {
+ imageView.setVisibility(mIconSpaceReserved ? View.INVISIBLE : View.GONE);
+ }
}
final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame);
@@ -931,6 +941,25 @@ public class Preference implements Comparable<Preference> {
}
/**
+ * Sets whether to reserve the space of this Preference icon view when no icon is provided.
+ *
+ * @param iconSpaceReserved set {@code true} if the space for the icon view should be reserved
+ */
+ public void setIconSpaceReserved(boolean iconSpaceReserved) {
+ mIconSpaceReserved = iconSpaceReserved;
+ notifyChanged();
+ }
+
+ /**
+ * Gets whether the space this preference icon view is reserved.
+ *
+ * @see #setIconSpaceReserved(boolean)
+ * @return {@code true} if the space of this preference icon view is reserved
+ */
+ public boolean isIconSpaceReserved() {
+ return mIconSpaceReserved;
+ }
+ /**
* Returns a unique ID for this Preference. This ID should be unique across all
* Preference objects in a hierarchy.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7005d44ee08a..e2100bd43898 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -396,38 +396,6 @@ public final class Settings {
"android.settings.WIFI_IP_SETTINGS";
/**
- * Activity Action: Show settings to allow the configuration of Wi-Fi features.
- * <p>
- * In some cases, a matching Activity may not exist, so ensure you
- * safeguard against this.
- * <p>
- * Input: Nothing.
- * <p>
- * Output: Nothing.
- * @hide
- */
- @SystemApi
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CONFIGURE_WIFI_SETTINGS =
- "android.settings.CONFIGURE_WIFI_SETTINGS";
-
- /**
- * Activity Action: Show settings to allow configuration of Wi-Fi saved networks.
- * <p>
- * In some cases, a matching Activity may not exist, so ensure you
- * safeguard against this.
- * <p>
- * Input: Nothing.
- * <p>
- * Output: Nothing.
- * @hide
- */
- @SystemApi
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_WIFI_SAVED_NETWORK_SETTINGS =
- "android.settings.WIFI_SAVED_NETWORK_SETTINGS";
-
- /**
* Activity Action: Show settings to allow configuration of Bluetooth.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -7109,6 +7077,15 @@ public final class Settings {
INSTANT_APP_SETTINGS.add(ENABLED_ACCESSIBILITY_SERVICES);
INSTANT_APP_SETTINGS.add(ACCESSIBILITY_SPEAK_PASSWORD);
INSTANT_APP_SETTINGS.add(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_ENABLED);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_PRESET);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_EDGE_TYPE);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_EDGE_COLOR);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_LOCALE);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_TYPEFACE);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_CAPTIONING_FONT_SCALE);
INSTANT_APP_SETTINGS.add(DEFAULT_INPUT_METHOD);
INSTANT_APP_SETTINGS.add(ENABLED_INPUT_METHODS);
@@ -8232,9 +8209,14 @@ public final class Settings {
* the open network(s) disappear, we remove the notification. When we
* show the notification, we will not show it again for
* {@link android.provider.Settings.Secure#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} time.
+ *
+ * @deprecated This feature is no longer controlled by this setting in
+ * {@link android.os.Build.VERSION_CODES#O}.
*/
+ @Deprecated
public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
"wifi_networks_available_notification_on";
+
/**
* {@hide}
*/
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index a8b094eab0a2..4c61c2f755a0 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -112,7 +112,7 @@ public class VoicemailContract {
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_VOICEMAIL_SMS_RECEIVED =
- "android.intent.action.VOICEMAIL_SMS_RECEIVED";
+ "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED";
/**
* Extra in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} indicating the content of the SMS.
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 21168475adf7..8e0103078a42 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -433,6 +433,7 @@ public class TileService extends Service {
public static final void requestListeningState(Context context, ComponentName component) {
Intent intent = new Intent(ACTION_REQUEST_LISTENING);
intent.putExtra(EXTRA_COMPONENT, component);
+ intent.setPackage("com.android.systemui");
context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE);
}
}
diff --git a/core/java/android/service/resolver/IResolverRankerResult.aidl b/core/java/android/service/resolver/IResolverRankerResult.aidl
new file mode 100644
index 000000000000..bda315420b7b
--- /dev/null
+++ b/core/java/android/service/resolver/IResolverRankerResult.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.resolver;
+
+import android.service.resolver.ResolverTarget;
+
+/**
+ * @hide
+ */
+oneway interface IResolverRankerResult
+{
+ void sendResult(in List<ResolverTarget> results);
+} \ No newline at end of file
diff --git a/core/java/android/service/resolver/IResolverRankerService.aidl b/core/java/android/service/resolver/IResolverRankerService.aidl
new file mode 100644
index 000000000000..f0d747d974a7
--- /dev/null
+++ b/core/java/android/service/resolver/IResolverRankerService.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.resolver;
+
+import android.service.resolver.IResolverRankerResult;
+import android.service.resolver.ResolverTarget;
+
+/**
+ * @hide
+ */
+oneway interface IResolverRankerService
+{
+ void predict(in List<ResolverTarget> targets, IResolverRankerResult result);
+ void train(in List<ResolverTarget> targets, int selectedPosition);
+} \ No newline at end of file
diff --git a/core/java/android/service/resolver/ResolverRankerService.java b/core/java/android/service/resolver/ResolverRankerService.java
new file mode 100644
index 000000000000..05067479bf45
--- /dev/null
+++ b/core/java/android/service/resolver/ResolverRankerService.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.resolver;
+
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.RemoteException;
+import android.service.resolver.ResolverTarget;
+import android.util.Log;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A service to rank apps according to usage stats of apps, when the system is resolving targets for
+ * an Intent.
+ *
+ * <p>To extend this class, you must declare the service in your manifest file with the
+ * {@link android.Manifest.permission#BIND_RESOLVER_RANKER_SERVICE} permission, and include an
+ * intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * <pre>
+ * &lt;service android:name=".MyResolverRankerService"
+ * android:exported="true"
+ * android:priority="100"
+ * android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"&gt;
+ * &lt;intent-filter&gt;
+ * &lt;action android:name="android.service.resolver.ResolverRankerService" /&gt;
+ * &lt;/intent-filter&gt;
+ * &lt;/service&gt;
+ * </pre>
+ * @hide
+ */
+@SystemApi
+public abstract class ResolverRankerService extends Service {
+
+ private static final String TAG = "ResolverRankerService";
+
+ private static final boolean DEBUG = false;
+
+ /**
+ * The Intent action that a service must respond to. Add it to the intent filter of the service
+ * in its manifest.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService";
+
+ /**
+ * The permission that a service must require to ensure that only Android system can bind to it.
+ * If this permission is not enforced in the AndroidManifest of the service, the system will
+ * skip that service.
+ */
+ public static final String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
+
+ private ResolverRankerServiceWrapper mWrapper = null;
+
+ /**
+ * Called by the system to retrieve a list of probabilities to rank apps/options. To implement
+ * it, set selectProbability of each input {@link ResolverTarget}. The higher the
+ * selectProbability is, the more likely the {@link ResolverTarget} will be selected by the
+ * user. Override this function to provide prediction results.
+ *
+ * @param targets a list of {@link ResolverTarget}, for the list of apps to be ranked.
+ *
+ * @throws Exception when the prediction task fails.
+ */
+ public void onPredictSharingProbabilities(final List<ResolverTarget> targets) {}
+
+ /**
+ * Called by the system to train/update a ranking service, after the user makes a selection from
+ * the ranked list of apps. Override this function to enable model updates.
+ *
+ * @param targets a list of {@link ResolverTarget}, for the list of apps to be ranked.
+ * @param selectedPosition the position of the selected app in the list.
+ *
+ * @throws Exception when the training task fails.
+ */
+ public void onTrainRankingModel(
+ final List<ResolverTarget> targets, final int selectedPosition) {}
+
+ private static final String HANDLER_THREAD_NAME = "RESOLVER_RANKER_SERVICE";
+ private volatile Handler mHandler;
+ private HandlerThread mHandlerThread;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (DEBUG) Log.d(TAG, "onBind " + intent);
+ if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ if (DEBUG) Log.d(TAG, "bad intent action " + intent.getAction() + "; returning null");
+ return null;
+ }
+ if (mHandlerThread == null) {
+ mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ }
+ if (mWrapper == null) {
+ mWrapper = new ResolverRankerServiceWrapper();
+ }
+ return mWrapper;
+ }
+
+ @Override
+ public void onDestroy() {
+ mHandler = null;
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ }
+ super.onDestroy();
+ }
+
+ private static void sendResult(List<ResolverTarget> targets, IResolverRankerResult result) {
+ try {
+ result.sendResult(targets);
+ } catch (Exception e) {
+ Log.e(TAG, "failed to send results: " + e);
+ }
+ }
+
+ private class ResolverRankerServiceWrapper extends IResolverRankerService.Stub {
+
+ @Override
+ public void predict(final List<ResolverTarget> targets, final IResolverRankerResult result)
+ throws RemoteException {
+ Runnable predictRunnable = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "predict calls onPredictSharingProbabilities.");
+ }
+ onPredictSharingProbabilities(targets);
+ sendResult(targets, result);
+ } catch (Exception e) {
+ Log.e(TAG, "onPredictSharingProbabilities failed; send null results: " + e);
+ sendResult(null, result);
+ }
+ }
+ };
+ final Handler h = mHandler;
+ if (h != null) {
+ h.post(predictRunnable);
+ }
+ }
+
+ @Override
+ public void train(final List<ResolverTarget> targets, final int selectedPosition)
+ throws RemoteException {
+ Runnable trainRunnable = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "train calls onTranRankingModel");
+ }
+ onTrainRankingModel(targets, selectedPosition);
+ } catch (Exception e) {
+ Log.e(TAG, "onTrainRankingModel failed; skip train: " + e);
+ }
+ }
+ };
+ final Handler h = mHandler;
+ if (h != null) {
+ h.post(trainRunnable);
+ }
+ }
+ }
+}
diff --git a/core/java/android/service/resolver/ResolverTarget.aidl b/core/java/android/service/resolver/ResolverTarget.aidl
new file mode 100644
index 000000000000..6cab2d4df908
--- /dev/null
+++ b/core/java/android/service/resolver/ResolverTarget.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.resolver;
+
+/**
+ * @hide
+ */
+parcelable ResolverTarget;
diff --git a/core/java/android/service/resolver/ResolverTarget.java b/core/java/android/service/resolver/ResolverTarget.java
new file mode 100644
index 000000000000..fb3e2d738469
--- /dev/null
+++ b/core/java/android/service/resolver/ResolverTarget.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.resolver;
+
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import java.util.Map;
+
+/**
+ * A ResolverTarget contains features by which an app or option will be ranked, in
+ * {@link ResolverRankerService}.
+ * @hide
+ */
+@SystemApi
+public final class ResolverTarget implements Parcelable {
+ private static final String TAG = "ResolverTarget";
+
+ /**
+ * a float score for recency of last use.
+ */
+ private float mRecencyScore;
+
+ /**
+ * a float score for total time spent.
+ */
+ private float mTimeSpentScore;
+
+ /**
+ * a float score for number of launches.
+ */
+ private float mLaunchScore;
+
+ /**
+ * a float score for number of selected.
+ */
+ private float mChooserScore;
+
+ /**
+ * a float score for the probability to be selected.
+ */
+ private float mSelectProbability;
+
+ // constructor for the class.
+ public ResolverTarget() {}
+
+ ResolverTarget(Parcel in) {
+ mRecencyScore = in.readFloat();
+ mTimeSpentScore = in.readFloat();
+ mLaunchScore = in.readFloat();
+ mChooserScore = in.readFloat();
+ mSelectProbability = in.readFloat();
+ }
+
+ /**
+ * Gets the score for how recently the target was used in the foreground.
+ *
+ * @return a float score whose range is [0, 1]. The higher the score is, the more recently the
+ * target was used.
+ */
+ public float getRecencyScore() {
+ return mRecencyScore;
+ }
+
+ /**
+ * Sets the score for how recently the target was used in the foreground.
+ *
+ * @param recencyScore a float score whose range is [0, 1]. The higher the score is, the more
+ * recently the target was used.
+ */
+ public void setRecencyScore(float recencyScore) {
+ this.mRecencyScore = recencyScore;
+ }
+
+ /**
+ * Gets the score for how long the target has been used in the foreground.
+ *
+ * @return a float score whose range is [0, 1]. The higher the score is, the longer the target
+ * has been used for.
+ */
+ public float getTimeSpentScore() {
+ return mTimeSpentScore;
+ }
+
+ /**
+ * Sets the score for how long the target has been used in the foreground.
+ *
+ * @param timeSpentScore a float score whose range is [0, 1]. The higher the score is, the
+ * longer the target has been used for.
+ */
+ public void setTimeSpentScore(float timeSpentScore) {
+ this.mTimeSpentScore = timeSpentScore;
+ }
+
+ /**
+ * Gets the score for how many times the target has been launched to the foreground.
+ *
+ * @return a float score whose range is [0, 1]. The higher the score is, the more times the
+ * target has been launched.
+ */
+ public float getLaunchScore() {
+ return mLaunchScore;
+ }
+
+ /**
+ * Sets the score for how many times the target has been launched to the foreground.
+ *
+ * @param launchScore a float score whose range is [0, 1]. The higher the score is, the more
+ * times the target has been launched.
+ */
+ public void setLaunchScore(float launchScore) {
+ this.mLaunchScore = launchScore;
+ }
+
+ /**
+ * Gets the score for how many times the target has been selected by the user to share the same
+ * types of content.
+ *
+ * @return a float score whose range is [0, 1]. The higher the score is, the
+ * more times the target has been selected by the user to share the same types of content for.
+ */
+ public float getChooserScore() {
+ return mChooserScore;
+ }
+
+ /**
+ * Sets the score for how many times the target has been selected by the user to share the same
+ * types of content.
+ *
+ * @param chooserScore a float score whose range is [0, 1]. The higher the score is, the more
+ * times the target has been selected by the user to share the same types
+ * of content for.
+ */
+ public void setChooserScore(float chooserScore) {
+ this.mChooserScore = chooserScore;
+ }
+
+ /**
+ * Gets the probability of how likely this target will be selected by the user.
+ *
+ * @return a float score whose range is [0, 1]. The higher the score is, the more likely the
+ * user is going to select this target.
+ */
+ public float getSelectProbability() {
+ return mSelectProbability;
+ }
+
+ /**
+ * Sets the probability for how like this target will be selected by the user.
+ *
+ * @param selectProbability a float score whose range is [0, 1]. The higher the score is, the
+ * more likely tht user is going to select this target.
+ */
+ public void setSelectProbability(float selectProbability) {
+ this.mSelectProbability = selectProbability;
+ }
+
+ // serialize the class to a string.
+ @Override
+ public String toString() {
+ return "ResolverTarget{"
+ + mRecencyScore + ", "
+ + mTimeSpentScore + ", "
+ + mLaunchScore + ", "
+ + mChooserScore + ", "
+ + mSelectProbability + "}";
+ }
+
+ // describes the kinds of special objects contained in this Parcelable instance's marshaled
+ // representation.
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ // flattens this object in to a Parcel.
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeFloat(mRecencyScore);
+ dest.writeFloat(mTimeSpentScore);
+ dest.writeFloat(mLaunchScore);
+ dest.writeFloat(mChooserScore);
+ dest.writeFloat(mSelectProbability);
+ }
+
+ // creator definition for the class.
+ public static final Creator<ResolverTarget> CREATOR
+ = new Creator<ResolverTarget>() {
+ @Override
+ public ResolverTarget createFromParcel(Parcel source) {
+ return new ResolverTarget(source);
+ }
+
+ @Override
+ public ResolverTarget[] newArray(int size) {
+ return new ResolverTarget[size];
+ }
+ };
+}
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index e59ec080e2c0..59ee8f360c12 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -137,7 +137,15 @@ public abstract class UtteranceProgressListener {
* @param end The end index of the range (exclusive) in the utterance text.
* @param frame The position in frames in the audio of the request where this range is spoken.
*/
- public void onRangeStart(String utteranceId, int start, int end, int frame) {}
+ public void onRangeStart(String utteranceId, int start, int end, int frame) {
+ onUtteranceRangeStart(utteranceId, start, end);
+ }
+
+ /**
+ * @deprecated Due to internal API changes. Remove when apps catch up.
+ */
+ public void onUtteranceRangeStart(String utteranceId, int start, int end) {
+ }
/**
* Wraps an old deprecated OnUtteranceCompletedListener with a shiny new progress listener.
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
index 70f9bdd9193b..14d3ad790b1d 100644
--- a/core/java/android/text/FontConfig.java
+++ b/core/java/android/text/FontConfig.java
@@ -22,13 +22,11 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.FontListParser;
+import android.net.Uri;
import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
-import java.io.IOException;
import java.lang.annotation.Retention;
-import java.util.Arrays;
/**
@@ -44,20 +42,6 @@ public final class FontConfig implements Parcelable {
}
/**
- * For duplicating file descriptors.
- *
- * Note that this copy constructor can not be usable for deep copy.
- * @hide
- */
- public FontConfig(@NonNull FontConfig config) {
- mFamilies = new Family[config.mFamilies.length];
- for (int i = 0; i < config.mFamilies.length; ++i) {
- mFamilies[i] = new Family(config.mFamilies[i]);
- }
- mAliases = Arrays.copyOf(config.mAliases, config.mAliases.length);
- }
-
- /**
* Returns the ordered list of families included in the system fonts.
*/
public @NonNull Family[] getFamilies() {
@@ -174,7 +158,7 @@ public final class FontConfig implements Parcelable {
private final @NonNull Axis[] mAxes;
private final int mWeight;
private final boolean mIsItalic;
- private @Nullable ParcelFileDescriptor mFd;
+ private Uri mUri;
/**
* @hide
@@ -186,29 +170,6 @@ public final class FontConfig implements Parcelable {
mAxes = axes;
mWeight = weight;
mIsItalic = isItalic;
- mFd = null;
- }
-
- /**
- * This is for duplicating FileDescriptors.
- *
- * Note that this copy ctor doesn't deep copy the members.
- *
- * @hide
- */
- public Font(Font origin) {
- mFontName = origin.mFontName;
- mTtcIndex = origin.mTtcIndex;
- mAxes = origin.mAxes;
- mWeight = origin.mWeight;
- mIsItalic = origin.mIsItalic;
- if (origin.mFd != null) {
- try {
- mFd = origin.mFd.dup();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
}
/**
@@ -247,17 +208,20 @@ public final class FontConfig implements Parcelable {
}
/**
- * Returns a file descriptor to access the specified font. This should be closed after use.
+ * Returns the content uri associated to this font.
+ *
+ * You can reach to the font contents by calling {@link
+ * android.content.ContentResolver#openInputStream}.
*/
- public @Nullable ParcelFileDescriptor getFd() {
- return mFd;
+ public @Nullable Uri getUri() {
+ return mUri;
}
/**
* @hide
*/
- public void setFd(@NonNull ParcelFileDescriptor fd) {
- mFd = fd;
+ public void setUri(@NonNull Uri uri) {
+ mUri = uri;
}
/**
@@ -269,11 +233,7 @@ public final class FontConfig implements Parcelable {
mAxes = in.createTypedArray(Axis.CREATOR);
mWeight = in.readInt();
mIsItalic = in.readInt() == 1;
- if (in.readInt() == 1) { /* has FD */
- mFd = ParcelFileDescriptor.CREATOR.createFromParcel(in);
- } else {
- mFd = null;
- }
+ mUri = in.readTypedObject(Uri.CREATOR);
}
@Override
@@ -283,10 +243,7 @@ public final class FontConfig implements Parcelable {
out.writeTypedArray(mAxes, flag);
out.writeInt(mWeight);
out.writeInt(mIsItalic ? 1 : 0);
- out.writeInt(mFd == null ? 0 : 1);
- if (mFd != null) {
- mFd.writeToParcel(out, flag);
- }
+ out.writeTypedObject(mUri, flag);
}
@Override
@@ -425,22 +382,6 @@ public final class FontConfig implements Parcelable {
}
/**
- * For duplicating file descriptor underlying Font object.
- *
- * This copy constructor is not for deep copying.
- * @hide
- */
- public Family(Family origin) {
- mName = origin.mName;
- mLanguage = origin.mLanguage;
- mVariant = origin.mVariant;
- mFonts = new Font[origin.mFonts.length];
- for (int i = 0; i < origin.mFonts.length; ++i) {
- mFonts[i] = new Font(origin.mFonts[i]);
- }
- }
-
- /**
* Returns the name given by the system to this font family.
*/
public @Nullable String getName() {
diff --git a/core/java/android/util/ExceptionUtils.java b/core/java/android/util/ExceptionUtils.java
index 87231e106ca3..44019c32560d 100644
--- a/core/java/android/util/ExceptionUtils.java
+++ b/core/java/android/util/ExceptionUtils.java
@@ -17,6 +17,7 @@
package android.util;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.ParcelableException;
import com.android.internal.util.Preconditions;
@@ -55,10 +56,26 @@ public class ExceptionUtils {
return getCompleteMessage(null, t);
}
+ public static <E extends Throwable> void propagateIfInstanceOf(
+ @Nullable Throwable t, Class<E> c) throws E {
+ if (t != null && c.isInstance(t)) {
+ throw c.cast(t);
+ }
+ }
+
+ /**
+ * @param <E> a checked exception that is ok to throw without wrapping
+ */
+ public static <E extends Exception> RuntimeException propagate(@NonNull Throwable t, Class<E> c)
+ throws E {
+ propagateIfInstanceOf(t, c);
+ return propagate(t);
+ }
+
public static RuntimeException propagate(@NonNull Throwable t) {
Preconditions.checkNotNull(t);
- if (t instanceof Error) throw (Error)t;
- if (t instanceof RuntimeException) throw (RuntimeException)t;
+ propagateIfInstanceOf(t, Error.class);
+ propagateIfInstanceOf(t, RuntimeException.class);
throw new RuntimeException(t);
}
}
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index 86318e91b885..d3cc175d3e1c 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -36,8 +36,8 @@ public class ContextThemeWrapper extends ContextWrapper {
/**
* Creates a new context wrapper with no theme and no base context.
- * <p>
- * <stong>Note:</strong> A base context <strong>must</strong> be attached
+ * <p class="note">
+ * <strong>Note:</strong> A base context <strong>must</strong> be attached
* using {@link #attachBaseContext(Context)} before calling any other
* method on the newly constructed context wrapper.
*/
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 61c92018a406..ae1ee42c8720 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -18,6 +18,7 @@ package android.view;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.SparseArray;
@@ -88,8 +89,9 @@ public class FocusFinder {
private View findNextFocus(ViewGroup root, View focused, Rect focusedRect, int direction) {
View next = null;
+ ViewGroup effectiveRoot = getEffectiveRoot(root, focused);
if (focused != null) {
- next = findNextUserSpecifiedFocus(root, focused, direction);
+ next = findNextUserSpecifiedFocus(effectiveRoot, focused, direction);
}
if (next != null) {
return next;
@@ -97,9 +99,9 @@ public class FocusFinder {
ArrayList<View> focusables = mTempList;
try {
focusables.clear();
- root.addFocusables(focusables, direction);
+ effectiveRoot.addFocusables(focusables, direction);
if (!focusables.isEmpty()) {
- next = findNextFocus(root, focused, focusedRect, direction, focusables);
+ next = findNextFocus(effectiveRoot, focused, focusedRect, direction, focusables);
}
} finally {
focusables.clear();
@@ -108,6 +110,35 @@ public class FocusFinder {
}
/**
+ * Returns the "effective" root of a view. The "effective" root is the closest ancestor
+ * within-which focus should cycle.
+ * <p>
+ * For example: normal focus navigation would stay within a ViewGroup marked as
+ * touchscreenBlocksFocus and keyboardNavigationCluster until a cluster-jump out.
+ * @return the "effective" root of {@param focused}
+ */
+ private ViewGroup getEffectiveRoot(ViewGroup root, View focused) {
+ if (focused == null) {
+ return root;
+ }
+ ViewParent effective = focused.getParent();
+ do {
+ if (effective == root) {
+ return root;
+ }
+ ViewGroup vg = (ViewGroup) effective;
+ if (vg.getTouchscreenBlocksFocus()
+ && focused.getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TOUCHSCREEN)
+ && vg.isKeyboardNavigationCluster()) {
+ return vg;
+ }
+ effective = effective.getParent();
+ } while (effective != null);
+ return root;
+ }
+
+ /**
* Find the root of the next keyboard navigation cluster after the current one.
* @param root The view tree to look inside. Cannot be null
* @param currentCluster The starting point of the search. Null means the default cluster
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index e59073999683..076b33cc9d6a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -137,7 +137,10 @@ public class SurfaceView extends View {
} break;
case DRAW_FINISHED_MSG: {
mDrawFinished = true;
- invalidate();
+ if (mAttachedToWindow) {
+ notifyDrawFinished();
+ invalidate();
+ }
} break;
}
}
@@ -188,9 +191,12 @@ public class SurfaceView extends View {
private Translator mTranslator;
private boolean mGlobalListenersAdded;
+ private boolean mAttachedToWindow;
private int mSurfaceFlags = SurfaceControl.HIDDEN;
+ private int mPendingReportDraws;
+
public SurfaceView(Context context) {
this(context, null);
}
@@ -227,6 +233,7 @@ public class SurfaceView extends View {
mViewVisibility = getVisibility() == VISIBLE;
mRequestedVisible = mViewVisibility && mWindowVisibility;
+ mAttachedToWindow = true;
if (!mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver();
observer.addOnScrollChangedListener(mScrollChangedListener);
@@ -261,8 +268,17 @@ public class SurfaceView extends View {
updateSurface();
}
+ void notifyDrawFinished() {
+ ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot != null) {
+ viewRoot.pendingDrawFinished();
+ }
+ mPendingReportDraws--;
+ }
+
@Override
protected void onDetachedFromWindow() {
+ mAttachedToWindow = false;
if (mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver();
observer.removeOnScrollChangedListener(mScrollChangedListener);
@@ -270,6 +286,10 @@ public class SurfaceView extends View {
mGlobalListenersAdded = false;
}
+ while (mPendingReportDraws > 0) {
+ notifyDrawFinished();
+ }
+
mRequestedVisible = false;
updateSurface();
@@ -618,6 +638,9 @@ public class SurfaceView extends View {
if (callbacks == null) {
callbacks = getSurfaceCallbacks();
}
+
+ mPendingReportDraws++;
+ viewRoot.drawPending();
SurfaceCallbackHelper sch =
new SurfaceCallbackHelper(this::onDrawFinished);
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6c73b9b5ecef..23fcb553ddbd 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -61,6 +61,7 @@ import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerGlobal;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -4170,14 +4171,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to
* request read access to the content URI(s) contained in the {@link ClipData} object.
- * @see android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION
+ * @see android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION
*/
public static final int DRAG_FLAG_GLOBAL_URI_READ = Intent.FLAG_GRANT_READ_URI_PERMISSION;
/**
* When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to
* request write access to the content URI(s) contained in the {@link ClipData} object.
- * @see android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ * @see android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION
*/
public static final int DRAG_FLAG_GLOBAL_URI_WRITE = Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
@@ -4185,8 +4186,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link
* #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant can be persisted across device
* reboots until explicitly revoked with
- * {@link android.content.Context#revokeUriPermission(Uri,int) Context.revokeUriPermission}.
- * @see android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+ * {@link android.content.Context#revokeUriPermission(Uri, int)} Context.revokeUriPermission}.
+ * @see android.content.Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION
*/
public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION =
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
@@ -4195,7 +4196,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link
* #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant applies to any URI that is a prefix
* match against the original granted URI.
- * @see android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
+ * @see android.content.Intent#FLAG_GRANT_PREFIX_URI_PERMISSION
*/
public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION =
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
@@ -7446,11 +7447,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* </pre>
*
* @param value value to be autofilled.
- *
- * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
*/
- public boolean autofill(@SuppressWarnings("unused") AutofillValue value) {
- return false;
+ public void autofill(@SuppressWarnings("unused") AutofillValue value) {
}
/**
@@ -7460,12 +7458,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info.
*
* @param values map of values to be autofilled, keyed by virtual child id.
- *
- * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
*/
- public boolean autofill(
- @NonNull @SuppressWarnings("unused") SparseArray<AutofillValue>values) {
- return false;
+ public void autofill(@NonNull @SuppressWarnings("unused") SparseArray<AutofillValue> values) {
}
/**
@@ -7895,7 +7889,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param arguments A {@link Bundle} holding any arguments relevant for this request. May be
* {@code null} if the service provided no arguments.
*
- * @see AccessibilityNodeInfo#setExtraAvailableData
+ * @see AccessibilityNodeInfo#setAvailableExtraData(List)
*/
public void addExtraDataToAccessibilityNodeInfo(
@NonNull AccessibilityNodeInfo info, @NonNull String extraDataKey,
@@ -9839,7 +9833,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a
* window or serves as a target of cluster navigation.
*
- * @see #restoreDefaultFocus(int)
+ * @see #restoreDefaultFocus()
*
* @return {@code true} if this view is the default-focus view, {@code false} otherwise
* @attr ref android.R.styleable#View_focusedByDefault
@@ -9859,7 +9853,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param isFocusedByDefault {@code true} to set this view as the default-focus view,
* {@code false} otherwise.
*
- * @see #restoreDefaultFocus(int)
+ * @see #restoreDefaultFocus()
*
* @attr ref android.R.styleable#View_focusedByDefault
*/
@@ -16457,29 +16451,34 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * @see #onMovedToDisplay(int)
+ * @see #onMovedToDisplay(int, Configuration)
*/
- void dispatchMovedToDisplay(Display display) {
+ void dispatchMovedToDisplay(Display display, Configuration config) {
mAttachInfo.mDisplay = display;
mAttachInfo.mDisplayState = display.getState();
- onMovedToDisplay(display.getDisplayId());
+ onMovedToDisplay(display.getDisplayId(), config);
}
/**
* Called by the system when the hosting activity is moved from one display to another without
* recreation. This means that the activity is declared to handle all changes to configuration
* that happened when it was switched to another display, so it wasn't destroyed and created
- * again. This call will be followed by {@link #onConfigurationChanged(Configuration)} if the
- * applied configuration actually changed.
+ * again.
+ *
+ * <p>This call will be followed by {@link #onConfigurationChanged(Configuration)} if the
+ * applied configuration actually changed. It is up to app developer to choose whether to handle
+ * the change in this method or in the following {@link #onConfigurationChanged(Configuration)}
+ * call.
*
* <p>Use this callback to track changes to the displays if some functionality relies on an
* association with some display properties.
*
* @param displayId The id of the display to which the view was moved.
+ * @param config Configuration of the resources on new display after move.
*
* @see #onConfigurationChanged(Configuration)
*/
- public void onMovedToDisplay(int displayId) {
+ public void onMovedToDisplay(int displayId, Configuration config) {
}
/**
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index f16fcc933b70..574137b30f1e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -232,10 +232,16 @@ public class ViewConfiguration {
private static final int OVERFLING_DISTANCE = 6;
/**
- * Amount to scroll in response to a {@link MotionEvent#ACTION_SCROLL} event, in dips per
- * axis value.
+ * Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event,
+ * in dips per axis value.
*/
- private static final int SCROLL_FACTOR = 64;
+ private static final float HORIZONTAL_SCROLL_FACTOR = 64;
+
+ /**
+ * Amount to scroll in response to a vertical {@link MotionEvent#ACTION_SCROLL} event,
+ * in dips per axis value.
+ */
+ private static final float VERTICAL_SCROLL_FACTOR = 64;
/**
* Default duration to hide an action mode for.
@@ -289,7 +295,8 @@ public class ViewConfiguration {
private final int mOverflingDistance;
private final boolean mFadingMarqueeEnabled;
private final long mGlobalActionsKeyTimeout;
- private final int mScrollFactor;
+ private final float mVerticalScrollFactor;
+ private final float mHorizontalScrollFactor;
private boolean sHasPermanentMenuKey;
private boolean sHasPermanentMenuKeySet;
@@ -319,7 +326,8 @@ public class ViewConfiguration {
mOverflingDistance = OVERFLING_DISTANCE;
mFadingMarqueeEnabled = true;
mGlobalActionsKeyTimeout = GLOBAL_ACTIONS_KEY_TIMEOUT;
- mScrollFactor = SCROLL_FACTOR;
+ mHorizontalScrollFactor = HORIZONTAL_SCROLL_FACTOR;
+ mVerticalScrollFactor = VERTICAL_SCROLL_FACTOR;
}
/**
@@ -406,8 +414,11 @@ public class ViewConfiguration {
com.android.internal.R.dimen.config_viewMaxFlingVelocity);
mGlobalActionsKeyTimeout = res.getInteger(
com.android.internal.R.integer.config_globalActionsKeyTimeout);
- mScrollFactor = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_scrollFactor);
+
+ mHorizontalScrollFactor = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.config_horizontalScrollFactor);
+ mVerticalScrollFactor = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.config_verticalScrollFactor);
}
/**
@@ -730,9 +741,27 @@ public class ViewConfiguration {
/**
* @return Amount to scroll in response to a {@link MotionEvent#ACTION_SCROLL} event. Multiply
* this by the event's axis value to obtain the number of pixels to be scrolled.
+ *
+ * @removed
*/
public int getScaledScrollFactor() {
- return mScrollFactor;
+ return (int) mVerticalScrollFactor;
+ }
+
+ /**
+ * @return Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event.
+ * Multiply this by the event's axis value to obtain the number of pixels to be scrolled.
+ */
+ public float getScaledHorizontalScrollFactor() {
+ return mHorizontalScrollFactor;
+ }
+
+ /**
+ * @return Amount to scroll in response to a vertical {@link MotionEvent#ACTION_SCROLL} event.
+ * Multiply this by the event's axis value to obtain the number of pixels to be scrolled.
+ */
+ public float getScaledVerticalScrollFactor() {
+ return mVerticalScrollFactor;
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index de0ec40ac97b..c250226ae713 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1190,7 +1190,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int focusableCount = views.size();
final int descendantFocusability = getDescendantFocusability();
- final boolean focusSelf = (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen());
+ final boolean blockFocusForTouchscreen = shouldBlockFocusForTouchscreen();
+ final boolean focusSelf = (isFocusableInTouchMode() || !blockFocusForTouchscreen);
if (descendantFocusability == FOCUS_BLOCK_DESCENDANTS) {
if (focusSelf) {
@@ -1199,7 +1200,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return;
}
- if (shouldBlockFocusForTouchscreen()) {
+ if (blockFocusForTouchscreen) {
focusableMode |= FOCUSABLES_TOUCH_MODE;
}
@@ -1234,7 +1235,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public void addKeyboardNavigationClusters(Collection<View> views, int direction) {
final int focusableCount = views.size();
- super.addKeyboardNavigationClusters(views, direction);
+ if (isKeyboardNavigationCluster()) {
+ // Cluster-navigation can enter a touchscreenBlocksFocus cluster, so temporarily
+ // disable touchscreenBlocksFocus to evaluate whether it contains focusables.
+ final boolean blockedFocus = getTouchscreenBlocksFocus();
+ try {
+ setTouchscreenBlocksFocusNoRefocus(false);
+ super.addKeyboardNavigationClusters(views, direction);
+ } finally {
+ setTouchscreenBlocksFocusNoRefocus(blockedFocus);
+ }
+ } else {
+ super.addKeyboardNavigationClusters(views, direction);
+ }
if (focusableCount != views.size()) {
// No need to look for groups inside a group.
@@ -1280,6 +1293,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
+ private void setTouchscreenBlocksFocusNoRefocus(boolean touchscreenBlocksFocus) {
+ if (touchscreenBlocksFocus) {
+ mGroupFlags |= FLAG_TOUCHSCREEN_BLOCKS_FOCUS;
+ } else {
+ mGroupFlags &= ~FLAG_TOUCHSCREEN_BLOCKS_FOCUS;
+ }
+ }
+
/**
* Check whether this ViewGroup should ignore focus requests for itself and its children.
*/
@@ -1288,8 +1309,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
boolean shouldBlockFocusForTouchscreen() {
+ // There is a special case for keyboard-navigation clusters. We allow cluster navigation
+ // to jump into blockFocusForTouchscreen ViewGroups which are clusters. Once in the
+ // cluster, focus is free to move around within it.
return getTouchscreenBlocksFocus() &&
- mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);
+ mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
+ && (!hasFocus() || !isKeyboardNavigationCluster());
}
@Override
@@ -3175,6 +3200,21 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@TestApi
@Override
public boolean restoreFocusInCluster(@FocusRealDirection int direction) {
+ // Allow cluster-navigation to enter touchscreenBlocksFocus ViewGroups.
+ if (isKeyboardNavigationCluster()) {
+ final boolean blockedFocus = getTouchscreenBlocksFocus();
+ try {
+ setTouchscreenBlocksFocusNoRefocus(false);
+ return restoreFocusInClusterInternal(direction);
+ } finally {
+ setTouchscreenBlocksFocusNoRefocus(blockedFocus);
+ }
+ } else {
+ return restoreFocusInClusterInternal(direction);
+ }
+ }
+
+ private boolean restoreFocusInClusterInternal(@FocusRealDirection int direction) {
if (mFocusedInCluster != null && !mFocusedInCluster.isKeyboardNavigationCluster()
&& getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS
&& (mFocusedInCluster.mViewFlags & VISIBILITY_MASK) == VISIBLE
@@ -3281,13 +3321,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
@Override
- void dispatchMovedToDisplay(Display display) {
- super.dispatchMovedToDisplay(display);
+ void dispatchMovedToDisplay(Display display, Configuration config) {
+ super.dispatchMovedToDisplay(display, config);
final int count = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
- children[i].dispatchMovedToDisplay(display);
+ children[i].dispatchMovedToDisplay(display, config);
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 168178702ebf..a43b13e659a0 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -28,6 +28,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import android.Manifest;
import android.animation.LayoutTransition;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ResourcesManager;
@@ -210,8 +211,11 @@ public final class ViewRootImpl implements ViewParent,
/**
* Always assign focus if a focusable View is available.
+ *
+ * @hide
*/
- private static boolean sAlwaysAssignFocus;
+ @TestApi
+ public static boolean sAlwaysAssignFocus;
/**
* This list must only be modified by the main thread, so a lock is only needed when changing
@@ -1106,10 +1110,11 @@ public final class ViewRootImpl implements ViewParent,
/**
* Notify about move to a different display.
* @param displayId The id of the display where this view root is moved to.
+ * @param config Configuration of the resources on new display after move.
*
* @hide
*/
- public void onMovedToDisplay(int displayId) {
+ public void onMovedToDisplay(int displayId, Configuration config) {
if (mDisplay.getDisplayId() == displayId) {
return;
}
@@ -1120,7 +1125,7 @@ public final class ViewRootImpl implements ViewParent,
mView.getResources());
mAttachInfo.mDisplayState = mDisplay.getState();
// Internal state updated, now notify the view hierarchy.
- mView.dispatchMovedToDisplay(mDisplay);
+ mView.dispatchMovedToDisplay(mDisplay, config);
}
void pokeDrawLockIfNeeded() {
@@ -2703,8 +2708,40 @@ public final class ViewRootImpl implements ViewParent,
}
}
- private void onDrawFinished() {
+ /**
+ * A count of the number of calls to pendingDrawFinished we
+ * require to notify the WM drawing is complete.
+ *
+ * This starts at 1, for the ViewRootImpl surface itself.
+ * Subsurfaces may debt the value with drawPending.
+ */
+ int mDrawsNeededToReport = 1;
+
+ /**
+ * Delay notifying WM of draw finished until
+ * a balanced call to pendingDrawFinished.
+ */
+ void drawPending() {
+ mDrawsNeededToReport++;
+ }
+
+ void pendingDrawFinished() {
+ if (mDrawsNeededToReport == 0) {
+ throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls");
+ }
+ mDrawsNeededToReport--;
+ if (mDrawsNeededToReport == 0) {
+ reportDrawFinished();
+ }
+ }
+
+ private void postDrawFinished() {
+ mHandler.sendEmptyMessage(MSG_DRAW_FINISHED);
+ }
+
+ private void reportDrawFinished() {
try {
+ mDrawsNeededToReport = 1;
mWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) {
// Have fun!
@@ -2761,15 +2798,12 @@ public final class ViewRootImpl implements ViewParent,
}
if (mSurfaceHolder != null && mSurface.isValid()) {
- SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished);
+ SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::postDrawFinished);
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
} else {
- try {
- mWindowSession.finishDrawing(mWindow);
- } catch (RemoteException e) {
- }
+ pendingDrawFinished();
}
}
}
@@ -3485,15 +3519,16 @@ public final class ViewRootImpl implements ViewParent,
mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId);
} else {
// There is no activity callback - update the configuration right away.
- updateConfiguration();
+ updateConfiguration(newDisplayId);
}
mForceNextConfigUpdate = false;
}
/**
* Update display and views if last applied merged configuration changed.
+ * @param newDisplayId Id of new display if moved, {@link Display#INVALID_DISPLAY} otherwise.
*/
- public void updateConfiguration() {
+ public void updateConfiguration(int newDisplayId) {
if (mView == null) {
return;
}
@@ -3503,6 +3538,13 @@ public final class ViewRootImpl implements ViewParent,
// the one in them which may be newer.
final Resources localResources = mView.getResources();
final Configuration config = localResources.getConfiguration();
+
+ // Handle move to display.
+ if (newDisplayId != INVALID_DISPLAY) {
+ onMovedToDisplay(newDisplayId, config);
+ }
+
+ // Handle configuration change.
if (mForceNextConfigUpdate || mLastConfigurationFromResources.diff(config) != 0) {
// Update the display with new DisplayAdjustments.
mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(
@@ -3567,6 +3609,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26;
private final static int MSG_UPDATE_POINTER_ICON = 27;
private final static int MSG_POINTER_CAPTURE_CHANGED = 28;
+ private final static int MSG_DRAW_FINISHED = 29;
final class ViewRootHandler extends Handler {
@Override
@@ -3618,6 +3661,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_UPDATE_POINTER_ICON";
case MSG_POINTER_CAPTURE_CHANGED:
return "MSG_POINTER_CAPTURE_CHANGED";
+ case MSG_DRAW_FINISHED:
+ return "MSG_DRAW_FINISHED";
}
return super.getMessageName(message);
}
@@ -3674,15 +3719,17 @@ public final class ViewRootImpl implements ViewParent,
SomeArgs args = (SomeArgs) msg.obj;
final int displayId = args.argi3;
+ final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
final boolean displayChanged = mDisplay.getDisplayId() != displayId;
- if (displayChanged) {
- onMovedToDisplay(displayId);
- }
- final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
if (mergedConfiguration != null) {
+ // If configuration changed - notify about that and, maybe, about move to
+ // display.
performConfigurationChange(mergedConfiguration, false /* force */,
displayChanged ? displayId : INVALID_DISPLAY /* same display */);
+ } else if (displayChanged) {
+ // Moved to display without config change - report last applied one.
+ onMovedToDisplay(displayId, mLastConfigurationFromResources);
}
final boolean framesChanged = !mWinFrame.equals(args.arg1)
@@ -3891,6 +3938,9 @@ public final class ViewRootImpl implements ViewParent,
final boolean hasCapture = msg.arg1 != 0;
handlePointerCaptureChanged(hasCapture);
} break;
+ case MSG_DRAW_FINISHED: {
+ pendingDrawFinished();
+ } break;
}
}
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b4d2c6bfe016..37ca5b3f6941 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -554,9 +554,8 @@ public final class AutofillManager {
}
valuesByParent.put(id.getVirtualChildId(), value);
} else {
- if (view.autofill(value)) {
- numApplied++;
- }
+ view.autofill(value);
+ numApplied++;
}
}
@@ -564,9 +563,8 @@ public final class AutofillManager {
for (int i = 0; i < virtualValues.size(); i++) {
final View parent = virtualValues.keyAt(i);
final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
- if (parent.autofill(childrenValues)) {
- numApplied += childrenValues.size();
- }
+ parent.autofill(childrenValues);
+ numApplied += childrenValues.size();
}
}
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 44309a7b68c2..28c2d016f6db 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -520,27 +520,27 @@ public final class InputMethodSubtype implements Parcelable {
}
private HashMap<String, String> getExtraValueHashMap() {
- if (mExtraValueHashMapCache == null) {
- synchronized(this) {
- if (mExtraValueHashMapCache == null) {
- mExtraValueHashMapCache = new HashMap<String, String>();
- final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR);
- final int N = pairs.length;
- for (int i = 0; i < N; ++i) {
- final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR);
- if (pair.length == 1) {
- mExtraValueHashMapCache.put(pair[0], null);
- } else if (pair.length > 1) {
- if (pair.length > 2) {
- Slog.w(TAG, "ExtraValue has two or more '='s");
- }
- mExtraValueHashMapCache.put(pair[0], pair[1]);
- }
+ synchronized (this) {
+ HashMap<String, String> extraValueMap = mExtraValueHashMapCache;
+ if (extraValueMap != null) {
+ return extraValueMap;
+ }
+ extraValueMap = new HashMap<>();
+ final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR);
+ for (int i = 0; i < pairs.length; ++i) {
+ final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR);
+ if (pair.length == 1) {
+ extraValueMap.put(pair[0], null);
+ } else if (pair.length > 1) {
+ if (pair.length > 2) {
+ Slog.w(TAG, "ExtraValue has two or more '='s");
}
+ extraValueMap.put(pair[0], pair[1]);
}
}
+ mExtraValueHashMapCache = extraValueMap;
+ return extraValueMap;
}
- return mExtraValueHashMapCache;
}
/**
diff --git a/core/java/android/view/textclassifier/SmartSelection.java b/core/java/android/view/textclassifier/SmartSelection.java
index 9397a4163e97..f0f39b683fbd 100644
--- a/core/java/android/view/textclassifier/SmartSelection.java
+++ b/core/java/android/view/textclassifier/SmartSelection.java
@@ -26,6 +26,11 @@ final class SmartSelection {
System.loadLibrary("textclassifier");
}
+ /** Hints the classifier that this may be a url. */
+ static final int HINT_FLAG_URL = 0x01;
+ /** Hints the classifier that this may be an email. */
+ static final int HINT_FLAG_EMAIL = 0x02;
+
private final long mCtx;
/**
@@ -59,8 +64,8 @@ final class SmartSelection {
* scores for different collections.
*/
public ClassificationResult[] classifyText(
- String context, int selectionBegin, int selectionEnd) {
- return nativeClassifyText(mCtx, context, selectionBegin, selectionEnd);
+ String context, int selectionBegin, int selectionEnd, int hintFlags) {
+ return nativeClassifyText(mCtx, context, selectionBegin, selectionEnd, hintFlags);
}
/**
@@ -76,7 +81,7 @@ final class SmartSelection {
long context, String text, int selectionBegin, int selectionEnd);
private static native ClassificationResult[] nativeClassifyText(
- long context, String text, int selectionBegin, int selectionEnd);
+ long context, String text, int selectionBegin, int selectionEnd, int hintFlags);
private static native void nativeClose(long context);
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 35c9a294d273..548796584dc8 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -44,8 +44,6 @@ public final class TextClassificationManager {
private final Object mLangIdLock = new Object();
private final Context mContext;
- // TODO: Implement a way to close the file descriptors.
- private ParcelFileDescriptor mSmartSelectionFd;
private ParcelFileDescriptor mLangIdFd;
private TextClassifier mDefault;
private LangId mLangId;
@@ -61,15 +59,7 @@ public final class TextClassificationManager {
public TextClassifier getDefaultTextClassifier() {
synchronized (mTextClassifierLock) {
if (mDefault == null) {
- try {
- mSmartSelectionFd = ParcelFileDescriptor.open(
- new File("/etc/textclassifier/textclassifier.smartselection.en.model"),
- ParcelFileDescriptor.MODE_READ_ONLY);
- mDefault = new TextClassifierImpl(mContext, mSmartSelectionFd);
- } catch (FileNotFoundException e) {
- Log.e(LOG_TAG, "Error accessing 'text classifier selection' model file.", e);
- mDefault = TextClassifier.NO_OP;
- }
+ mDefault = new TextClassifierImpl(mContext);
}
return mDefault;
}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index be12f5702129..f634a1b52675 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -35,19 +35,27 @@ import android.text.method.WordIterator;
import android.text.style.ClickableSpan;
import android.text.util.Linkify;
import android.util.Log;
+import android.util.Patterns;
import android.view.View;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
+import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Default implementation of the {@link TextClassifier} interface.
@@ -61,16 +69,21 @@ import java.util.Map;
final class TextClassifierImpl implements TextClassifier {
private static final String LOG_TAG = "TextClassifierImpl";
-
- private final Object mSmartSelectionLock = new Object();
+ private static final String MODEL_DIR = "/etc/textclassifier/";
+ private static final String MODEL_FILE_REGEX = "textclassifier\\.smartselection\\.(.*)\\.model";
private final Context mContext;
- private final ParcelFileDescriptor mFd;
+
+ private final Object mSmartSelectionLock = new Object();
+ @GuardedBy("mSmartSelectionLock") // Do not access outside this lock.
+ private Map<Locale, String> mModelFilePaths;
+ @GuardedBy("mSmartSelectionLock") // Do not access outside this lock.
+ private Locale mLocale;
+ @GuardedBy("mSmartSelectionLock") // Do not access outside this lock.
private SmartSelection mSmartSelection;
- TextClassifierImpl(Context context, ParcelFileDescriptor fd) {
+ TextClassifierImpl(Context context) {
mContext = Preconditions.checkNotNull(context);
- mFd = Preconditions.checkNotNull(fd);
}
@Override
@@ -80,15 +93,18 @@ final class TextClassifierImpl implements TextClassifier {
validateInput(text, selectionStartIndex, selectionEndIndex);
try {
if (text.length() > 0) {
+ final SmartSelection smartSelection = getSmartSelection(defaultLocales);
final String string = text.toString();
- final int[] startEnd = getSmartSelection()
- .suggest(string, selectionStartIndex, selectionEndIndex);
+ final int[] startEnd = smartSelection.suggest(
+ string, selectionStartIndex, selectionEndIndex);
final int start = startEnd[0];
final int end = startEnd[1];
if (start >= 0 && end <= string.length() && start <= end) {
final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
final SmartSelection.ClassificationResult[] results =
- getSmartSelection().classifyText(string, start, end);
+ smartSelection.classifyText(
+ string, start, end,
+ getHintFlags(string, start, end));
final int size = results.length;
for (int i = 0; i < size; i++) {
tsBuilder.setEntityType(results[i].mCollection, results[i].mScore);
@@ -116,12 +132,14 @@ final class TextClassifierImpl implements TextClassifier {
validateInput(text, startIndex, endIndex);
try {
if (text.length() > 0) {
- final CharSequence classified = text.subSequence(startIndex, endIndex);
- SmartSelection.ClassificationResult[] results = getSmartSelection()
- .classifyText(text.toString(), startIndex, endIndex);
+ final String string = text.toString();
+ SmartSelection.ClassificationResult[] results = getSmartSelection(defaultLocales)
+ .classifyText(string, startIndex, endIndex,
+ getHintFlags(string, startIndex, endIndex));
if (results.length > 0) {
final TextClassificationResult classificationResult =
- createClassificationResult(results, classified);
+ createClassificationResult(
+ results, string.subSequence(startIndex, endIndex));
// TODO: Added this log for debug only. Remove before release.
Log.d(LOG_TAG, String.format(
"Classification type: %s", classificationResult));
@@ -142,7 +160,7 @@ final class TextClassifierImpl implements TextClassifier {
Preconditions.checkArgument(text != null);
try {
return LinksInfoFactory.create(
- mContext, getSmartSelection(), text.toString(), linkMask);
+ mContext, getSmartSelection(defaultLocales), text.toString(), linkMask);
} catch (Throwable t) {
// Avoid throwing from this method. Log the error.
Log.e(LOG_TAG, "Error getting links info.", t);
@@ -151,15 +169,69 @@ final class TextClassifierImpl implements TextClassifier {
return TextClassifier.NO_OP.getLinks(text, linkMask, defaultLocales);
}
- private SmartSelection getSmartSelection() throws FileNotFoundException {
+ private SmartSelection getSmartSelection(LocaleList localeList) throws FileNotFoundException {
synchronized (mSmartSelectionLock) {
- if (mSmartSelection == null) {
- mSmartSelection = new SmartSelection(mFd.getFd());
+ localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
+ final Locale locale = findBestSupportedLocaleLocked(localeList);
+ if (mSmartSelection == null || !Objects.equals(mLocale, locale)) {
+ destroySmartSelectionIfExistsLocked();
+ mSmartSelection = new SmartSelection(
+ ParcelFileDescriptor.open(
+ // findBestSupportedLocaleLocked should have initialized
+ // mModelFilePaths
+ new File(mModelFilePaths.get(locale)),
+ ParcelFileDescriptor.MODE_READ_ONLY)
+ .getFd());
+ mLocale = locale;
}
return mSmartSelection;
}
}
+ @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
+ private void destroySmartSelectionIfExistsLocked() {
+ if (mSmartSelection != null) {
+ mSmartSelection.close();
+ mSmartSelection = null;
+ }
+ }
+
+ @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
+ @Nullable
+ private Locale findBestSupportedLocaleLocked(LocaleList localeList) {
+ final List<Locale.LanguageRange> languageRangeList = Locale.LanguageRange.parse(
+ new StringJoiner(",")
+ // Specified localeList takes priority over the system default
+ .add(localeList.toLanguageTags())
+ .add(LocaleList.getDefault().toLanguageTags())
+ .toString());
+ return Locale.lookup(languageRangeList, loadModelFilePathsLocked().keySet());
+ }
+
+ @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
+ private Map<Locale, String> loadModelFilePathsLocked() {
+ if (mModelFilePaths == null) {
+ final Map<Locale, String> modelFilePaths = new HashMap<>();
+ final File modelsDir = new File(MODEL_DIR);
+ if (modelsDir.exists() && modelsDir.isDirectory()) {
+ final File[] models = modelsDir.listFiles();
+ final Pattern modelFilenamePattern = Pattern.compile(MODEL_FILE_REGEX);
+ final int size = models.length;
+ for (int i = 0; i < size; i++) {
+ final File modelFile = models[i];
+ final Matcher matcher = modelFilenamePattern.matcher(modelFile.getName());
+ if (matcher.matches() && modelFile.isFile()) {
+ final String language = matcher.group(1);
+ final Locale locale = Locale.forLanguageTag(language);
+ modelFilePaths.put(locale, modelFile.getAbsolutePath());
+ }
+ }
+ }
+ mModelFilePaths = modelFilePaths;
+ }
+ return mModelFilePaths;
+ }
+
private TextClassificationResult createClassificationResult(
SmartSelection.ClassificationResult[] classifications, CharSequence text) {
final TextClassificationResult.Builder builder = new TextClassificationResult.Builder()
@@ -208,6 +280,24 @@ final class TextClassifierImpl implements TextClassifier {
return builder.build();
}
+ private static int getHintFlags(CharSequence text, int start, int end) {
+ int flag = 0;
+ final CharSequence subText = text.subSequence(start, end);
+ if (Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(subText).matches()) {
+ flag |= SmartSelection.HINT_FLAG_EMAIL;
+ }
+ if (Patterns.AUTOLINK_WEB_URL.matcher(subText).matches()
+ && Linkify.sUrlMatchFilter.acceptMatch(text, start, end)) {
+ flag |= SmartSelection.HINT_FLAG_URL;
+ }
+ // TODO: Added this log for debug only. Remove before release.
+ Log.d(LOG_TAG, String.format("Email hint: %b",
+ (flag & SmartSelection.HINT_FLAG_EMAIL) != 0));
+ Log.d(LOG_TAG, String.format("Url hint: %b",
+ (flag & SmartSelection.HINT_FLAG_URL) != 0));
+ return flag;
+ }
+
private static String getHighestScoringType(SmartSelection.ClassificationResult[] types) {
if (types.length < 1) {
return "";
@@ -262,7 +352,9 @@ final class TextClassifierImpl implements TextClassifier {
if (selectionStart >= 0 && selectionEnd <= text.length()
&& selectionStart <= selectionEnd) {
final SmartSelection.ClassificationResult[] results =
- smartSelection.classifyText(text, selectionStart, selectionEnd);
+ smartSelection.classifyText(
+ text, selectionStart, selectionEnd,
+ getHintFlags(text, selectionStart, selectionEnd));
if (results.length > 0) {
final String type = getHighestScoringType(results);
if (matches(type, linkMask)) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c2b4138b90db..bc491230aa60 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -18,6 +18,7 @@ package android.webkit;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.Widget;
import android.content.Context;
@@ -58,6 +59,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
+import android.view.textclassifier.TextClassifier;
import android.widget.AbsoluteLayout;
import java.io.BufferedWriter;
@@ -2249,6 +2251,23 @@ public class WebView extends AbsoluteLayout
public boolean getRendererPriorityWaivedWhenNotVisible() {
return mProvider.getRendererPriorityWaivedWhenNotVisible();
}
+
+ /**
+ * Sets the {@link TextClassifier} for this WebView.
+ */
+ public void setTextClassifier(@Nullable TextClassifier textClassifier) {
+ mProvider.setTextClassifier(textClassifier);
+ }
+
+ /**
+ * Returns the {@link TextClassifier} used by this WebView.
+ * If no TextClassifier has been set, this WebView uses the default set by the system.
+ */
+ @NonNull
+ public TextClassifier getTextClassifier() {
+ return mProvider.getTextClassifier();
+ }
+
//-------------------------------------------------------------------------
// Interface for WebView providers
//-------------------------------------------------------------------------
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 81c2f5d5ef4c..71db6b141ca9 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -280,6 +280,44 @@ public final class WebViewFactory {
}
}
+ /**
+ * If the ApplicationInfo provided is for a stub WebView, fix up the object to include the
+ * required values from the donor package. If the ApplicationInfo is for a full WebView,
+ * leave it alone. Throws MissingWebViewPackageException if the donor is missing.
+ */
+ private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm) {
+ String donorPackageName = null;
+ if (ai.metaData != null) {
+ donorPackageName = ai.metaData.getString("com.android.webview.WebViewDonorPackage");
+ }
+ if (donorPackageName != null) {
+ PackageInfo donorPackage;
+ try {
+ donorPackage = pm.getPackageInfo(
+ donorPackageName,
+ PackageManager.GET_SHARED_LIBRARY_FILES
+ | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
+ | PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_FACTORY_ONLY);
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new MissingWebViewPackageException("Failed to find donor package: " +
+ donorPackageName);
+ }
+ ApplicationInfo donorInfo = donorPackage.applicationInfo;
+
+ // Replace the stub's code locations with the donor's.
+ ai.sourceDir = donorInfo.sourceDir;
+ ai.splitSourceDirs = donorInfo.splitSourceDirs;
+ ai.nativeLibraryDir = donorInfo.nativeLibraryDir;
+ ai.secondaryNativeLibraryDir = donorInfo.secondaryNativeLibraryDir;
+
+ // Copy the donor's primary and secondary ABIs, since the stub doesn't have native code
+ // and so they are unset.
+ ai.primaryCpuAbi = donorInfo.primaryCpuAbi;
+ ai.secondaryCpuAbi = donorInfo.secondaryCpuAbi;
+ }
+ }
+
private static Context getWebViewContextAndSetProvider() {
Application initialApplication = AppGlobals.getInitialApplication();
try {
@@ -307,9 +345,10 @@ public final class WebViewFactory {
}
// Fetch package info and verify it against the chosen package
PackageInfo newPackageInfo = null;
+ PackageManager pm = initialApplication.getPackageManager();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "PackageManager.getPackageInfo()");
try {
- newPackageInfo = initialApplication.getPackageManager().getPackageInfo(
+ newPackageInfo = pm.getPackageInfo(
response.packageInfo.packageName,
PackageManager.GET_SHARED_LIBRARY_FILES
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING
@@ -328,12 +367,15 @@ public final class WebViewFactory {
// failure
verifyPackageInfo(response.packageInfo, newPackageInfo);
+ ApplicationInfo ai = newPackageInfo.applicationInfo;
+ fixupStubApplicationInfo(ai, pm);
+
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW,
"initialApplication.createApplicationContext");
try {
// Construct an app context to load the Java code into the current app.
Context webViewContext = initialApplication.createApplicationContext(
- newPackageInfo.applicationInfo,
+ ai,
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
sPackageInfo = newPackageInfo;
return webViewContext;
@@ -449,7 +491,11 @@ public final class WebViewFactory {
*/
public static int onWebViewProviderChanged(PackageInfo packageInfo) {
String[] nativeLibs = null;
+ String originalSourceDir = packageInfo.applicationInfo.sourceDir;
try {
+ fixupStubApplicationInfo(packageInfo.applicationInfo,
+ AppGlobals.getInitialApplication().getPackageManager());
+
nativeLibs = WebViewFactory.getWebViewNativeLibraryPaths(packageInfo);
if (nativeLibs != null) {
long newVmSize = 0L;
@@ -498,7 +544,7 @@ public final class WebViewFactory {
Log.e(LOGTAG, "error preparing webview native library", t);
}
- WebViewZygote.onWebViewProviderChanged(packageInfo);
+ WebViewZygote.onWebViewProviderChanged(packageInfo, originalSourceDir);
return prepareWebViewInSystemServer(nativeLibs);
}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 5724a9b24052..aa1ffa25931d 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -16,6 +16,8 @@
package android.webkit;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.res.Configuration;
import android.content.Intent;
@@ -41,6 +43,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
+import android.view.textclassifier.TextClassifier;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebView.PictureListener;
import android.webkit.WebView.VisualStateCallback;
@@ -275,6 +278,12 @@ public interface WebViewProvider {
public boolean getRendererPriorityWaivedWhenNotVisible();
+ @SuppressWarnings("unused")
+ public default void setTextClassifier(@Nullable TextClassifier textClassifier) {}
+
+ @NonNull
+ public default TextClassifier getTextClassifier() { return TextClassifier.NO_OP; }
+
//-------------------------------------------------------------------------
// Provider internal methods
//-------------------------------------------------------------------------
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index f78d62250029..2123debfeb67 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -67,6 +67,13 @@ public class WebViewZygote {
private static PackageInfo sPackage;
/**
+ * Cache key for the selected WebView package's classloader. This is set from
+ * #onWebViewProviderChanged().
+ */
+ @GuardedBy("sLock")
+ private static String sPackageCacheKey;
+
+ /**
* Flag for whether multi-process WebView is enabled. If this is false, the zygote
* will not be started.
*/
@@ -118,9 +125,10 @@ public class WebViewZygote {
}
}
- public static void onWebViewProviderChanged(PackageInfo packageInfo) {
+ public static void onWebViewProviderChanged(PackageInfo packageInfo, String cacheKey) {
synchronized (sLock) {
sPackage = packageInfo;
+ sPackageCacheKey = cacheKey;
// If multi-process is not enabled, then do not start the zygote service.
if (!sMultiprocessEnabled) {
@@ -210,7 +218,8 @@ public class WebViewZygote {
TextUtils.join(File.pathSeparator, zipPaths);
Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
- sZygote.preloadPackageForAbi(zip, librarySearchPath, Build.SUPPORTED_ABIS[0]);
+ sZygote.preloadPackageForAbi(zip, librarySearchPath, sPackageCacheKey,
+ Build.SUPPORTED_ABIS[0]);
} catch (Exception e) {
Log.e(LOGTAG, "Error connecting to " + serviceName, e);
sZygote = null;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1937187defed..1c87726b3ca9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -618,7 +618,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mTouchSlop;
private float mDensityScale;
- private float mScrollFactor;
+ private float mVerticalScrollFactor;
private InputConnection mDefInputConnection;
private InputConnectionWrapper mPublicInputConnection;
@@ -877,7 +877,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop();
- mScrollFactor = configuration.getScaledScrollFactor();
+ mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance();
@@ -4225,7 +4225,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
axisValue = 0;
}
- final int delta = Math.round(axisValue * mScrollFactor);
+ final int delta = Math.round(axisValue * mVerticalScrollFactor);
if (delta != 0) {
if (!trackMotionScroll(delta, delta)) {
return true;
@@ -6873,9 +6873,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mTransientStateViews.put(position, scrap);
} else {
// Otherwise, we'll have to remove the view and start over.
+ clearScrapForRebind(scrap);
getSkippedScrap().add(scrap);
}
} else {
+ clearScrapForRebind(scrap);
if (mViewTypeCount == 1) {
mCurrentScrap.add(scrap);
} else {
@@ -7098,12 +7100,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
} else if (params.scrappedFromPosition == position) {
final View scrap = scrapViews.remove(i);
- clearAccessibilityFromScrap(scrap);
+ clearScrapForRebind(scrap);
return scrap;
}
}
final View scrap = scrapViews.remove(size - 1);
- clearAccessibilityFromScrap(scrap);
+ clearScrapForRebind(scrap);
return scrap;
} else {
return null;
@@ -7117,7 +7119,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
- private void clearAccessibilityFromScrap(View view) {
+ private void clearScrapForRebind(View view) {
view.clearAccessibilityFocus();
view.setAccessibilityDelegate(null);
}
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index 8f662ba79d5f..352e7de967dd 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -526,15 +526,15 @@ public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> {
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isList()) {
- setSelection(value.getListValue());
- } else {
+ if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return true;
+
+ setSelection(value.getListValue());
}
@Override
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 9dc61ab56b34..c7ba7b5d5a48 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -584,16 +584,15 @@ public abstract class CompoundButton extends Button implements Checkable {
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isToggle()) {
- setChecked(value.getToggleValue());
- } else {
+ if (!value.isToggle()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return true;
+ setChecked(value.getToggleValue());
}
@Override
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 7d04f355f251..463ff587466a 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -775,16 +775,15 @@ public class DatePicker extends FrameLayout {
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isDate()) {
- mDelegate.updateDate(value.getDateValue());
- } else {
+ if (!value.isDate()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return true;
+ mDelegate.updateDate(value.getDateValue());
}
@Override
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 918b6c0d65ff..da00d9c970b1 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -129,7 +129,7 @@ public class HorizontalScrollView extends FrameLayout {
private int mOverscrollDistance;
private int mOverflingDistance;
- private float mScrollFactor;
+ private float mHorizontalScrollFactor;
/**
* ID of the active pointer. This is used to retain consistency during
@@ -224,7 +224,7 @@ public class HorizontalScrollView extends FrameLayout {
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
- mScrollFactor = configuration.getScaledScrollFactor();
+ mHorizontalScrollFactor = configuration.getScaledHorizontalScrollFactor();
}
@Override
@@ -743,7 +743,7 @@ public class HorizontalScrollView extends FrameLayout {
axisValue = 0;
}
- final int delta = Math.round(axisValue * mScrollFactor);
+ final int delta = Math.round(axisValue * mHorizontalScrollFactor);
if (delta != 0) {
final int range = getScrollRange();
int oldScrollX = mScrollX;
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 78d18fdbca5f..ab4cce479005 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -523,9 +523,17 @@ public class ListPopupWindow implements ShowableListMenu {
/**
* Sets the height of the popup window in pixels. Can also be {@link #MATCH_PARENT}.
*
- * @param height Height of the popup window.
+ * @param height Height of the popup window must be a positive value,
+ * {@link #MATCH_PARENT}, or {@link #WRAP_CONTENT}.
+ *
+ * @throws IllegalArgumentException if height is set to negative value
*/
public void setHeight(int height) {
+ if (height < 0 && ViewGroup.LayoutParams.WRAP_CONTENT != height
+ && ViewGroup.LayoutParams.MATCH_PARENT != height) {
+ throw new IllegalArgumentException(
+ "Invalid height. Must be a positive value, MATCH_PARENT, or WRAP_CONTENT.");
+ }
mDropDownHeight = height;
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 1c0c4ef7cba7..12e35a14e381 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1639,7 +1639,7 @@ public class ListView extends AbsListView {
final View focusChild = getAccessibilityFocusedChild(focusHost);
if (focusChild != null) {
if (!dataChanged || isDirectChildHeaderOrFooter(focusChild)
- || focusChild.hasTransientState() || mAdapterHasStableIds) {
+ || (focusChild.hasTransientState() && mAdapterHasStableIds)) {
// The views won't be changing, so try to maintain
// focus on the current host and virtual view.
accessibilityFocusLayoutRestoreView = focusHost;
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index b63b899d5c92..59fb02d353bb 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -2064,7 +2064,7 @@ public class PopupWindow {
}
if (update) {
- update(mAnchor.get(), p);
+ update(mAnchor != null ? mAnchor.get() : null, p);
}
}
@@ -2178,9 +2178,14 @@ public class PopupWindow {
update = true;
}
- final View anchor = mAnchor.get();
- final int newAccessibilityIdOfAnchor = (anchor != null)
- ? anchor.getAccessibilityViewId() : -1;
+ View anchor = null;
+ int newAccessibilityIdOfAnchor = -1;
+
+ if (mAnchor != null && mAnchor.get() != null) {
+ anchor = mAnchor.get();
+ newAccessibilityIdOfAnchor = anchor.getAccessibilityViewId();
+ }
+
if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) {
p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor;
update = true;
@@ -2366,7 +2371,8 @@ public class PopupWindow {
}
private class PopupDecorView extends FrameLayout {
- private TransitionListenerAdapter mPendingExitListener;
+ /** Runnable used to clean up listeners after exit transition. */
+ private Runnable mCleanupAfterExit;
public PopupDecorView(Context context) {
super(context);
@@ -2477,7 +2483,7 @@ public class PopupWindow {
* <p>
* <strong>Note:</strong> The transition listener is guaranteed to have
* its {@code onTransitionEnd} method called even if the transition
- * never starts; however, it may be called with a {@code null} argument.
+ * never starts.
*/
public void startExitTransition(@NonNull Transition transition,
@Nullable final View anchorRoot, @Nullable final Rect epicenter,
@@ -2493,25 +2499,32 @@ public class PopupWindow {
anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
}
- // The exit listener MUST be called for cleanup, even if the
- // transition never starts or ends. Stash it for later.
- mPendingExitListener = new TransitionListenerAdapter() {
- @Override
- public void onTransitionEnd(Transition t) {
- if (anchorRoot != null) {
- anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
- }
-
- listener.onTransitionEnd(t);
+ // The cleanup runnable MUST be called even if the transition is
+ // canceled before it starts (and thus can't call onTransitionEnd).
+ mCleanupAfterExit = () -> {
+ listener.onTransitionEnd(transition);
- // The listener was called. Our job here is done.
- mPendingExitListener = null;
- t.removeListener(this);
+ if (anchorRoot != null) {
+ anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
}
+
+ // The listener was called. Our job here is done.
+ mCleanupAfterExit = null;
};
final Transition exitTransition = transition.clone();
- exitTransition.addListener(mPendingExitListener);
+ exitTransition.addListener(new TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition t) {
+ t.removeListener(this);
+
+ // This null check shouldn't be necessary, but it's easier
+ // to check here than it is to test every possible case.
+ if (mCleanupAfterExit != null) {
+ mCleanupAfterExit.run();
+ }
+ }
+ });
exitTransition.setEpicenterCallback(new EpicenterCallback() {
@Override
public Rect onGetEpicenter(Transition transition) {
@@ -2539,8 +2552,10 @@ public class PopupWindow {
public void cancelTransitions() {
TransitionManager.endTransitions(this);
- if (mPendingExitListener != null) {
- mPendingExitListener.onTransitionEnd(null);
+ // If the cleanup runnable is still around, that means the
+ // transition never started. We should run it now to clean up.
+ if (mCleanupAfterExit != null) {
+ mCleanupAfterExit.run();
}
}
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index a7574c7a45ae..08e657559e17 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -426,24 +426,22 @@ public class RadioGroup extends LinearLayout {
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- int index;
- if (value.isList()) {
- index = value.getListValue();
- } else {
+ if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
- return false;
+ return;
}
+ final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
- return false;
+ return;
}
+
check(child.getId());
- return true;
}
@Override
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index d8f337926073..0a9e361a20c4 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -135,7 +135,7 @@ public class ScrollView extends FrameLayout {
private int mOverscrollDistance;
private int mOverflingDistance;
- private int mScrollFactor;
+ private float mVerticalScrollFactor;
/**
* ID of the active pointer. This is used to retain consistency during
@@ -250,7 +250,7 @@ public class ScrollView extends FrameLayout {
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
- mScrollFactor = configuration.getScaledScrollFactor();
+ mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor();
}
@Override
@@ -796,7 +796,7 @@ public class ScrollView extends FrameLayout {
axisValue = 0;
}
- final int delta = Math.round(axisValue * mScrollFactor);
+ final int delta = Math.round(axisValue * mVerticalScrollFactor);
if (delta != 0) {
final int range = getScrollRange();
int oldScrollY = mScrollY;
@@ -1875,7 +1875,7 @@ public class ScrollView extends FrameLayout {
@Override
public String toString() {
- return "HorizontalScrollView.SavedState{"
+ return "ScrollView.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " scrollPosition=" + scrollPosition + "}";
}
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index a03238374f39..003db061c140 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -289,7 +289,7 @@ final class SelectionActionModeHelper {
*/
private static final class TextClassificationHelper {
- private static final int TRIM_DELTA = 50; // characters
+ private static final int TRIM_DELTA = 120; // characters
private TextClassifier mTextClassifier;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bc7c79d2e701..02afee32153b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10050,17 +10050,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
- public boolean autofill(AutofillValue value) {
- if (value.isText()) {
- if (isTextEditable()) {
- setText(value.getTextValue(), mBufferType, true, 0);
- return true;
- }
- } else {
+ public void autofill(AutofillValue value) {
+ if (!value.isText() || !isTextEditable()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return false;
+ setText(value.getTextValue(), mBufferType, true, 0);
}
@Override
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 1e97e3ba5134..0289dada0fd9 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -530,16 +530,14 @@ public class TimePicker extends FrameLayout {
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isDate()) {
- mDelegate.setDate(value.getDateValue());
- } else {
+ if (!value.isDate()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
}
- return true;
+ mDelegate.setDate(value.getDateValue());
}
@Override
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 2eb50e082041..bf3085d6f1d1 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -343,6 +343,9 @@ public class Toolbar extends ViewGroup {
final ViewGroup vgParent = (ViewGroup) parent;
if (vgParent.isKeyboardNavigationCluster()) {
setKeyboardNavigationCluster(false);
+ if (vgParent.getTouchscreenBlocksFocus()) {
+ setTouchscreenBlocksFocus(false);
+ }
break;
}
parent = vgParent.getParent();
diff --git a/core/java/com/android/internal/app/LRResolverRankerService.java b/core/java/com/android/internal/app/LRResolverRankerService.java
new file mode 100644
index 000000000000..1cad7c770b7c
--- /dev/null
+++ b/core/java/com/android/internal/app/LRResolverRankerService.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Environment;
+import android.os.IBinder;
+import android.os.storage.StorageManager;
+import android.service.resolver.ResolverRankerService;
+import android.service.resolver.ResolverTarget;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A Logistic Regression based {@link android.service.resolver.ResolverRankerService}, to be used
+ * in {@link ResolverComparator}.
+ */
+public final class LRResolverRankerService extends ResolverRankerService {
+ private static final String TAG = "LRResolverRankerService";
+
+ private static final boolean DEBUG = false;
+
+ private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
+ private static final String BIAS_PREF_KEY = "bias";
+ private static final String VERSION_PREF_KEY = "version";
+
+ private static final String LAUNCH_SCORE = "launch";
+ private static final String TIME_SPENT_SCORE = "timeSpent";
+ private static final String RECENCY_SCORE = "recency";
+ private static final String CHOOSER_SCORE = "chooser";
+
+ // parameters for a pre-trained model, to initialize the app ranker. When updating the
+ // pre-trained model, please update these params, as well as initModel().
+ private static final int CURRENT_VERSION = 1;
+ private static final float LEARNING_RATE = 0.0001f;
+ private static final float REGULARIZER_PARAM = 0.0001f;
+
+ private SharedPreferences mParamSharedPref;
+ private ArrayMap<String, Float> mFeatureWeights;
+ private float mBias;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ initModel();
+ return super.onBind(intent);
+ }
+
+ @Override
+ public void onPredictSharingProbabilities(List<ResolverTarget> targets) {
+ final int size = targets.size();
+ for (int i = 0; i < size; ++i) {
+ ResolverTarget target = targets.get(i);
+ ArrayMap<String, Float> features = getFeatures(target);
+ target.setSelectProbability(predict(features));
+ }
+ }
+
+ @Override
+ public void onTrainRankingModel(List<ResolverTarget> targets, int selectedPosition) {
+ final int size = targets.size();
+ if (selectedPosition < 0 || selectedPosition >= size) {
+ if (DEBUG) {
+ Log.d(TAG, "Invalid Position of Selected App " + selectedPosition);
+ }
+ return;
+ }
+ final ArrayMap<String, Float> positive = getFeatures(targets.get(selectedPosition));
+ final float positiveProbability = targets.get(selectedPosition).getSelectProbability();
+ final int targetSize = targets.size();
+ for (int i = 0; i < targetSize; ++i) {
+ if (i == selectedPosition) {
+ continue;
+ }
+ final ArrayMap<String, Float> negative = getFeatures(targets.get(i));
+ final float negativeProbability = targets.get(i).getSelectProbability();
+ if (negativeProbability > positiveProbability) {
+ update(negative, negativeProbability, false);
+ update(positive, positiveProbability, true);
+ }
+ }
+ commitUpdate();
+ }
+
+ private void initModel() {
+ mParamSharedPref = getParamSharedPref();
+ mFeatureWeights = new ArrayMap<>(4);
+ if (mParamSharedPref == null ||
+ mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
+ // Initializing the app ranker to a pre-trained model. When updating the pre-trained
+ // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
+ // REGULARIZER_PARAM.
+ mBias = -1.6568f;
+ mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
+ mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
+ mFeatureWeights.put(RECENCY_SCORE, 0.269f);
+ mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
+ } else {
+ mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
+ mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
+ mFeatureWeights.put(
+ TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
+ mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
+ mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
+ }
+ }
+
+ private ArrayMap<String, Float> getFeatures(ResolverTarget target) {
+ ArrayMap<String, Float> features = new ArrayMap<>(4);
+ features.put(RECENCY_SCORE, target.getRecencyScore());
+ features.put(TIME_SPENT_SCORE, target.getTimeSpentScore());
+ features.put(LAUNCH_SCORE, target.getLaunchScore());
+ features.put(CHOOSER_SCORE, target.getChooserScore());
+ return features;
+ }
+
+ private float predict(ArrayMap<String, Float> target) {
+ if (target == null) {
+ return 0.0f;
+ }
+ final int featureSize = target.size();
+ float sum = 0.0f;
+ for (int i = 0; i < featureSize; i++) {
+ String featureName = target.keyAt(i);
+ float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
+ sum += weight * target.valueAt(i);
+ }
+ return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
+ }
+
+ private void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
+ if (target == null) {
+ return;
+ }
+ final int featureSize = target.size();
+ float error = isSelected ? 1.0f - predict : -predict;
+ for (int i = 0; i < featureSize; i++) {
+ String featureName = target.keyAt(i);
+ float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
+ mBias += LEARNING_RATE * error;
+ currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
+ LEARNING_RATE * error * target.valueAt(i);
+ mFeatureWeights.put(featureName, currentWeight);
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
+ }
+ }
+
+ private void commitUpdate() {
+ try {
+ SharedPreferences.Editor editor = mParamSharedPref.edit();
+ editor.putFloat(BIAS_PREF_KEY, mBias);
+ final int size = mFeatureWeights.size();
+ for (int i = 0; i < size; i++) {
+ editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
+ }
+ editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
+ editor.apply();
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to commit update" + e);
+ }
+ }
+
+ private SharedPreferences getParamSharedPref() {
+ // The package info in the context isn't initialized in the way it is for normal apps,
+ // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
+ // build the path manually below using the same policy that appears in ContextImpl.
+ if (DEBUG) {
+ Log.d(TAG, "Context Package Name: " + getPackageName());
+ }
+ final File prefsFile = new File(new File(
+ Environment.getDataUserCePackageDirectory(
+ StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
+ "shared_prefs"),
+ PARAM_SHARED_PREF_NAME + ".xml");
+ return getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
+ }
+} \ No newline at end of file
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3f1c9adb1b68..622b70843cc2 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -530,6 +530,9 @@ public class ResolverActivity extends Activity {
getMainThreadHandler().removeCallbacks(mPostListReadyRunnable);
mPostListReadyRunnable = null;
}
+ if (mAdapter != null && mAdapter.mResolverListController != null) {
+ mAdapter.mResolverListController.destroy();
+ }
}
@Override
diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java
index 096fcb83e755..73b62a5fe60d 100644
--- a/core/java/com/android/internal/app/ResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverComparator.java
@@ -26,20 +26,34 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.SharedPreferences;
+import android.content.ServiceConnection;
import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
import android.os.storage.StorageManager;
import android.os.UserHandle;
+import android.service.resolver.IResolverRankerService;
+import android.service.resolver.IResolverRankerResult;
+import android.service.resolver.ResolverRankerService;
+import android.service.resolver.ResolverTarget;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import java.io.File;
+import java.lang.InterruptedException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -61,11 +75,15 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
private static final float RECENCY_MULTIPLIER = 2.f;
- // feature names used in ranking.
- private static final String LAUNCH_SCORE = "launch";
- private static final String TIME_SPENT_SCORE = "timeSpent";
- private static final String RECENCY_SCORE = "recency";
- private static final String CHOOSER_SCORE = "chooser";
+ // message types
+ private static final int RESOLVER_RANKER_SERVICE_RESULT = 0;
+ private static final int RESOLVER_RANKER_RESULT_TIMEOUT = 1;
+
+ // timeout for establishing connections with a ResolverRankerService.
+ private static final int CONNECTION_COST_TIMEOUT_MILLIS = 200;
+ // timeout for establishing connections with a ResolverRankerService, collecting features and
+ // predicting ranking scores.
+ private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
private final Collator mCollator;
private final boolean mHttp;
@@ -74,18 +92,74 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
private final Map<String, UsageStats> mStats;
private final long mCurrentTime;
private final long mSinceTime;
- private final LinkedHashMap<ComponentName, ScoredTarget> mScoredTargets = new LinkedHashMap<>();
+ private final LinkedHashMap<ComponentName, ResolverTarget> mTargetsDict = new LinkedHashMap<>();
private final String mReferrerPackage;
+ private final Object mLock = new Object();
+ private ArrayList<ResolverTarget> mTargets;
private String mContentType;
private String[] mAnnotations;
private String mAction;
- private LogisticRegressionAppRanker mRanker;
+ private IResolverRankerService mRanker;
+ private ResolverRankerServiceConnection mConnection;
+ private AfterCompute mAfterCompute;
+ private Context mContext;
+ private CountDownLatch mConnectSignal;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case RESOLVER_RANKER_SERVICE_RESULT:
+ if (DEBUG) {
+ Log.d(TAG, "RESOLVER_RANKER_SERVICE_RESULT");
+ }
+ if (mHandler.hasMessages(RESOLVER_RANKER_RESULT_TIMEOUT)) {
+ if (msg.obj != null) {
+ final List<ResolverTarget> receivedTargets =
+ (List<ResolverTarget>) msg.obj;
+ if (receivedTargets != null && mTargets != null
+ && receivedTargets.size() == mTargets.size()) {
+ final int size = mTargets.size();
+ for (int i = 0; i < size; ++i) {
+ mTargets.get(i).setSelectProbability(
+ receivedTargets.get(i).getSelectProbability());
+ }
+ } else {
+ Log.e(TAG, "Sizes of sent and received ResolverTargets diff.");
+ }
+ } else {
+ Log.e(TAG, "Receiving null prediction results.");
+ }
+ mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT);
+ mAfterCompute.afterCompute();
+ }
+ break;
+
+ case RESOLVER_RANKER_RESULT_TIMEOUT:
+ if (DEBUG) {
+ Log.d(TAG, "RESOLVER_RANKER_RESULT_TIMEOUT; unbinding services");
+ }
+ mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT);
+ mAfterCompute.afterCompute();
+ break;
- public ResolverComparator(Context context, Intent intent, String referrerPackage) {
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ };
+
+ public interface AfterCompute {
+ public void afterCompute ();
+ }
+
+ public ResolverComparator(Context context, Intent intent, String referrerPackage,
+ AfterCompute afterCompute) {
mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
String scheme = intent.getScheme();
mHttp = "http".equals(scheme) || "https".equals(scheme);
mReferrerPackage = referrerPackage;
+ mAfterCompute = afterCompute;
+ mContext = context;
mPm = context.getPackageManager();
mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
@@ -96,9 +170,9 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
mContentType = intent.getType();
getContentAnnotations(intent);
mAction = intent.getAction();
- mRanker = new LogisticRegressionAppRanker(context);
}
+ // get annotations of content from intent.
public void getContentAnnotations(Intent intent) {
ArrayList<String> annotations = intent.getStringArrayListExtra(
Intent.EXTRA_CONTENT_ANNOTATIONS);
@@ -114,20 +188,24 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
}
}
+ public void setCallBack(AfterCompute afterCompute) {
+ mAfterCompute = afterCompute;
+ }
+
+ // compute features for each target according to usage stats of targets.
public void compute(List<ResolvedComponentInfo> targets) {
- mScoredTargets.clear();
+ reset();
final long recentSinceTime = mCurrentTime - RECENCY_TIME_PERIOD;
- long mostRecentlyUsedTime = recentSinceTime + 1;
- long mostTimeSpent = 1;
- int mostLaunched = 1;
- int mostSelected = 1;
+ float mostRecencyScore = 1.0f;
+ float mostTimeSpentScore = 1.0f;
+ float mostLaunchScore = 1.0f;
+ float mostChooserScore = 1.0f;
for (ResolvedComponentInfo target : targets) {
- final ScoredTarget scoredTarget
- = new ScoredTarget(target.getResolveInfoAt(0).activityInfo);
- mScoredTargets.put(target.name, scoredTarget);
+ final ResolverTarget resolverTarget = new ResolverTarget();
+ mTargetsDict.put(target.name, resolverTarget);
final UsageStats pkStats = mStats.get(target.name.getPackageName());
if (pkStats != null) {
// Only count recency for apps that weren't the caller
@@ -135,31 +213,33 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
// Persistent processes muck this up, so omit them too.
if (!target.name.getPackageName().equals(mReferrerPackage)
&& !isPersistentProcess(target)) {
- final long lastTimeUsed = pkStats.getLastTimeUsed();
- scoredTarget.lastTimeUsed = lastTimeUsed;
- if (lastTimeUsed > mostRecentlyUsedTime) {
- mostRecentlyUsedTime = lastTimeUsed;
+ final float recencyScore =
+ (float) Math.max(pkStats.getLastTimeUsed() - recentSinceTime, 0);
+ resolverTarget.setRecencyScore(recencyScore);
+ if (recencyScore > mostRecencyScore) {
+ mostRecencyScore = recencyScore;
}
}
- final long timeSpent = pkStats.getTotalTimeInForeground();
- scoredTarget.timeSpent = timeSpent;
- if (timeSpent > mostTimeSpent) {
- mostTimeSpent = timeSpent;
+ final float timeSpentScore = (float) pkStats.getTotalTimeInForeground();
+ resolverTarget.setTimeSpentScore(timeSpentScore);
+ if (timeSpentScore > mostTimeSpentScore) {
+ mostTimeSpentScore = timeSpentScore;
}
- final int launched = pkStats.mLaunchCount;
- scoredTarget.launchCount = launched;
- if (launched > mostLaunched) {
- mostLaunched = launched;
+ final float launchScore = (float) pkStats.mLaunchCount;
+ resolverTarget.setLaunchScore(launchScore);
+ if (launchScore > mostLaunchScore) {
+ mostLaunchScore = launchScore;
}
- int selected = 0;
+ float chooserScore = 0.0f;
if (pkStats.mChooserCounts != null && mAction != null
&& pkStats.mChooserCounts.get(mAction) != null) {
- selected = pkStats.mChooserCounts.get(mAction).getOrDefault(mContentType, 0);
+ chooserScore = (float) pkStats.mChooserCounts.get(mAction)
+ .getOrDefault(mContentType, 0);
if (mAnnotations != null) {
final int size = mAnnotations.length;
for (int i = 0; i < size; i++) {
- selected += pkStats.mChooserCounts.get(mAction)
+ chooserScore += (float) pkStats.mChooserCounts.get(mAction)
.getOrDefault(mAnnotations[i], 0);
}
}
@@ -169,44 +249,37 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
Log.d(TAG, "Action type is null");
} else {
Log.d(TAG, "Chooser Count of " + mAction + ":" +
- target.name.getPackageName() + " is " + Integer.toString(selected));
+ target.name.getPackageName() + " is " +
+ Float.toString(chooserScore));
}
}
- scoredTarget.chooserCount = selected;
- if (selected > mostSelected) {
- mostSelected = selected;
+ resolverTarget.setChooserScore(chooserScore);
+ if (chooserScore > mostChooserScore) {
+ mostChooserScore = chooserScore;
}
}
}
-
if (DEBUG) {
- Log.d(TAG, "compute - mostRecentlyUsedTime: " + mostRecentlyUsedTime
- + " mostTimeSpent: " + mostTimeSpent
- + " recentSinceTime: " + recentSinceTime
- + " mostLaunched: " + mostLaunched);
+ Log.d(TAG, "compute - mostRecencyScore: " + mostRecencyScore
+ + " mostTimeSpentScore: " + mostTimeSpentScore
+ + " mostLaunchScore: " + mostLaunchScore
+ + " mostChooserScore: " + mostChooserScore);
}
- for (ScoredTarget target : mScoredTargets.values()) {
- final float recency = (float) Math.max(target.lastTimeUsed - recentSinceTime, 0)
- / (mostRecentlyUsedTime - recentSinceTime);
- target.setFeatures((float) target.launchCount / mostLaunched,
- (float) target.timeSpent / mostTimeSpent,
- recency * recency * RECENCY_MULTIPLIER,
- (float) target.chooserCount / mostSelected);
- target.selectProb = mRanker.predict(target.getFeatures());
+ mTargets = new ArrayList<>(mTargetsDict.values());
+ for (ResolverTarget target : mTargets) {
+ final float recency = target.getRecencyScore() / mostRecencyScore;
+ setFeatures(target, recency * recency * RECENCY_MULTIPLIER,
+ target.getLaunchScore() / mostLaunchScore,
+ target.getTimeSpentScore() / mostTimeSpentScore,
+ target.getChooserScore() / mostChooserScore);
+ addDefaultSelectProbability(target);
if (DEBUG) {
Log.d(TAG, "Scores: " + target);
}
}
- }
-
- static boolean isPersistentProcess(ResolvedComponentInfo rci) {
- if (rci != null && rci.getCount() > 0) {
- return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags &
- ApplicationInfo.FLAG_PERSISTENT) != 0;
- }
- return false;
+ predictSelectProbabilities(mTargets);
}
@Override
@@ -245,16 +318,16 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
// Pinned items stay stable within a normal lexical sort and ignore scoring.
if (!lPinned && !rPinned) {
if (mStats != null) {
- final ScoredTarget lhsTarget = mScoredTargets.get(new ComponentName(
+ final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
lhs.activityInfo.packageName, lhs.activityInfo.name));
- final ScoredTarget rhsTarget = mScoredTargets.get(new ComponentName(
+ final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
rhs.activityInfo.packageName, rhs.activityInfo.name));
- final int selectProbDiff = Float.compare(
- rhsTarget.selectProb, lhsTarget.selectProb);
+ final int selectProbabilityDiff = Float.compare(
+ rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
- if (selectProbDiff != 0) {
- return selectProbDiff > 0 ? 1 : -1;
+ if (selectProbabilityDiff != 0) {
+ return selectProbabilityDiff > 0 ? 1 : -1;
}
}
}
@@ -268,177 +341,234 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> {
}
public float getScore(ComponentName name) {
- final ScoredTarget target = mScoredTargets.get(name);
+ final ResolverTarget target = mTargetsDict.get(name);
if (target != null) {
- return target.selectProb;
+ return target.getSelectProbability();
}
return 0;
}
- static class ScoredTarget {
- public final ComponentInfo componentInfo;
- public long lastTimeUsed;
- public long timeSpent;
- public long launchCount;
- public long chooserCount;
- public ArrayMap<String, Float> features;
- public float selectProb;
-
- public ScoredTarget(ComponentInfo ci) {
- componentInfo = ci;
- features = new ArrayMap<>(5);
+ public void updateChooserCounts(String packageName, int userId, String action) {
+ if (mUsm != null) {
+ mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
}
+ }
- @Override
- public String toString() {
- return "ScoredTarget{" + componentInfo
- + " lastTimeUsed: " + lastTimeUsed
- + " timeSpent: " + timeSpent
- + " launchCount: " + launchCount
- + " chooserCount: " + chooserCount
- + " selectProb: " + selectProb
- + "}";
+ // update ranking model when the connection to it is valid.
+ public void updateModel(ComponentName componentName) {
+ synchronized (mLock) {
+ if (mRanker != null) {
+ try {
+ int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet())
+ .indexOf(componentName);
+ if (selectedPos > 0) {
+ mRanker.train(mTargets, selectedPos);
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Selected a unknown component: " + componentName);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in Train: " + e);
+ }
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Ranker is null; skip updateModel.");
+ }
+ }
}
+ }
- public void setFeatures(float launchCountScore, float usageTimeScore, float recencyScore,
- float chooserCountScore) {
- features.put(LAUNCH_SCORE, launchCountScore);
- features.put(TIME_SPENT_SCORE, usageTimeScore);
- features.put(RECENCY_SCORE, recencyScore);
- features.put(CHOOSER_SCORE, chooserCountScore);
+ // unbind the service and clear unhandled messges.
+ public void destroy() {
+ mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT);
+ mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT);
+ if (mConnection != null) {
+ mContext.unbindService(mConnection);
+ mConnection.destroy();
}
-
- public ArrayMap<String, Float> getFeatures() {
- return features;
+ if (DEBUG) {
+ Log.d(TAG, "Unbinded Resolver Ranker.");
}
}
- public void updateChooserCounts(String packageName, int userId, String action) {
- if (mUsm != null) {
- mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
+ // connect to a ranking service.
+ private void initRanker(Context context) {
+ synchronized (mLock) {
+ if (mConnection != null && mRanker != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Ranker still exists; reusing the existing one.");
+ }
+ return;
+ }
}
- }
-
- public void updateModel(ComponentName componentName) {
- if (mScoredTargets == null || componentName == null ||
- !mScoredTargets.containsKey(componentName)) {
+ Intent intent = resolveRankerService();
+ if (intent == null) {
return;
}
- ScoredTarget selected = mScoredTargets.get(componentName);
- for (ComponentName targetComponent : mScoredTargets.keySet()) {
- if (targetComponent.equals(componentName)) {
+ mConnectSignal = new CountDownLatch(1);
+ mConnection = new ResolverRankerServiceConnection(mConnectSignal);
+ context.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+ }
+
+ // resolve the service for ranking.
+ private Intent resolveRankerService() {
+ Intent intent = new Intent(ResolverRankerService.SERVICE_INTERFACE);
+ final List<ResolveInfo> resolveInfos = mPm.queryIntentServices(intent, 0);
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ if (resolveInfo == null || resolveInfo.serviceInfo == null
+ || resolveInfo.serviceInfo.applicationInfo == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Failed to retrieve a ranker: " + resolveInfo);
+ }
continue;
}
- ScoredTarget target = mScoredTargets.get(targetComponent);
- // A potential point of optimization. Save updates or derive a closed form for the
- // positive case, to avoid calculating them repeatedly.
- if (target.selectProb >= selected.selectProb) {
- mRanker.update(target.getFeatures(), target.selectProb, false);
- mRanker.update(selected.getFeatures(), selected.selectProb, true);
+ ComponentName componentName = new ComponentName(
+ resolveInfo.serviceInfo.applicationInfo.packageName,
+ resolveInfo.serviceInfo.name);
+ try {
+ final String perm = mPm.getServiceInfo(componentName, 0).permission;
+ if (!ResolverRankerService.BIND_PERMISSION.equals(perm)) {
+ Log.w(TAG, "ResolverRankerService " + componentName + " does not require"
+ + " permission " + ResolverRankerService.BIND_PERMISSION
+ + " - this service will not be queried for ResolverComparator."
+ + " add android:permission=\""
+ + ResolverRankerService.BIND_PERMISSION + "\""
+ + " to the <service> tag for " + componentName
+ + " in the manifest.");
+ continue;
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Could not look up service " + componentName
+ + "; component name not found");
+ continue;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Succeeded to retrieve a ranker: " + componentName);
}
+ intent.setComponent(componentName);
+ return intent;
}
- mRanker.commitUpdate();
+ return null;
}
- class LogisticRegressionAppRanker {
- private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
- private static final String BIAS_PREF_KEY = "bias";
- private static final String VERSION_PREF_KEY = "version";
-
- // parameters for a pre-trained model, to initialize the app ranker. When updating the
- // pre-trained model, please update these params, as well as initModel().
- private static final int CURRENT_VERSION = 1;
- private static final float LEARNING_RATE = 0.0001f;
- private static final float REGULARIZER_PARAM = 0.0001f;
+ // set a watchdog, to avoid waiting for ranking service for too long.
+ private void startWatchDog(int timeOutLimit) {
+ if (DEBUG) Log.d(TAG, "Setting watchdog timer for " + timeOutLimit + "ms");
+ if (mHandler == null) {
+ Log.d(TAG, "Error: Handler is Null; Needs to be initialized.");
+ }
+ mHandler.sendEmptyMessageDelayed(RESOLVER_RANKER_RESULT_TIMEOUT, timeOutLimit);
+ }
- private SharedPreferences mParamSharedPref;
- private ArrayMap<String, Float> mFeatureWeights;
- private float mBias;
+ private class ResolverRankerServiceConnection implements ServiceConnection {
+ private final CountDownLatch mConnectSignal;
- public LogisticRegressionAppRanker(Context context) {
- mParamSharedPref = getParamSharedPref(context);
- initModel();
+ public ResolverRankerServiceConnection(CountDownLatch connectSignal) {
+ mConnectSignal = connectSignal;
}
- public float predict(ArrayMap<String, Float> target) {
- if (target == null) {
- return 0.0f;
- }
- final int featureSize = target.size();
- float sum = 0.0f;
- for (int i = 0; i < featureSize; i++) {
- String featureName = target.keyAt(i);
- float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
- sum += weight * target.valueAt(i);
+ public final IResolverRankerResult resolverRankerResult =
+ new IResolverRankerResult.Stub() {
+ @Override
+ public void sendResult(List<ResolverTarget> targets) throws RemoteException {
+ if (DEBUG) {
+ Log.d(TAG, "Sending Result back to Resolver: " + targets);
+ }
+ synchronized (mLock) {
+ final Message msg = Message.obtain();
+ msg.what = RESOLVER_RANKER_SERVICE_RESULT;
+ msg.obj = targets;
+ mHandler.sendMessage(msg);
+ }
}
- return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
- }
+ };
- public void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
- if (target == null) {
- return;
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (DEBUG) {
+ Log.d(TAG, "onServiceConnected: " + name);
}
- final int featureSize = target.size();
- float error = isSelected ? 1.0f - predict : -predict;
- for (int i = 0; i < featureSize; i++) {
- String featureName = target.keyAt(i);
- float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
- mBias += LEARNING_RATE * error;
- currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
- LEARNING_RATE * error * target.valueAt(i);
- mFeatureWeights.put(featureName, currentWeight);
+ synchronized (mLock) {
+ mRanker = IResolverRankerService.Stub.asInterface(service);
+ mConnectSignal.countDown();
}
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
if (DEBUG) {
- Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
+ Log.d(TAG, "onServiceDisconnected: " + name);
+ }
+ synchronized (mLock) {
+ destroy();
}
}
- public void commitUpdate() {
- SharedPreferences.Editor editor = mParamSharedPref.edit();
- editor.putFloat(BIAS_PREF_KEY, mBias);
- final int size = mFeatureWeights.size();
- for (int i = 0; i < size; i++) {
- editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
+ public void destroy() {
+ synchronized (mLock) {
+ mRanker = null;
}
- editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
- editor.apply();
}
+ }
- private SharedPreferences getParamSharedPref(Context context) {
- // The package info in the context isn't initialized in the way it is for normal apps,
- // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
- // build the path manually below using the same policy that appears in ContextImpl.
+ private void reset() {
+ mTargetsDict.clear();
+ mTargets = null;
+ startWatchDog(WATCHDOG_TIMEOUT_MILLIS);
+ initRanker(mContext);
+ }
+
+ // predict select probabilities if ranking service is valid.
+ private void predictSelectProbabilities(List<ResolverTarget> targets) {
+ if (mConnection == null) {
if (DEBUG) {
- Log.d(TAG, "Context Package Name: " + context.getPackageName());
+ Log.d(TAG, "Has not found valid ResolverRankerService; Skip Prediction");
+ }
+ return;
+ } else {
+ try {
+ mConnectSignal.await(CONNECTION_COST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ synchronized (mLock) {
+ if (mRanker != null) {
+ mRanker.predict(targets, mConnection.resolverRankerResult);
+ return;
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Ranker has not been initialized; skip predict.");
+ }
+ }
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Error in Wait for Service Connection.");
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in Predict: " + e);
}
- final File prefsFile = new File(new File(
- Environment.getDataUserCePackageDirectory(StorageManager.UUID_PRIVATE_INTERNAL,
- context.getUserId(), context.getPackageName()),
- "shared_prefs"),
- PARAM_SHARED_PREF_NAME + ".xml");
- return context.getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
}
+ mAfterCompute.afterCompute();
+ }
- private void initModel() {
- mFeatureWeights = new ArrayMap<>(4);
- if (mParamSharedPref == null ||
- mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
- // Initializing the app ranker to a pre-trained model. When updating the pre-trained
- // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
- // REGULARIZER_PARAM.
- mBias = -1.6568f;
- mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
- mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
- mFeatureWeights.put(RECENCY_SCORE, 0.269f);
- mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
- } else {
- mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
- mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
- mFeatureWeights.put(
- TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
- mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
- mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
- }
+ // adds select prob as the default values, according to a pre-trained Logistic Regression model.
+ private void addDefaultSelectProbability(ResolverTarget target) {
+ float sum = 2.5543f * target.getLaunchScore() + 2.8412f * target.getTimeSpentScore() +
+ 0.269f * target.getRecencyScore() + 4.2222f * target.getChooserScore();
+ target.setSelectProbability((float) (1.0 / (1.0 + Math.exp(1.6568f - sum))));
+ }
+
+ // sets features for each target
+ private void setFeatures(ResolverTarget target, float recencyScore, float launchScore,
+ float timeSpentScore, float chooserScore) {
+ target.setRecencyScore(recencyScore);
+ target.setLaunchScore(launchScore);
+ target.setTimeSpentScore(timeSpentScore);
+ target.setChooserScore(chooserScore);
+ }
+
+ static boolean isPersistentProcess(ResolvedComponentInfo rci) {
+ if (rci != null && rci.getCount() > 0) {
+ return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags &
+ ApplicationInfo.FLAG_PERSISTENT) != 0;
}
+ return false;
}
}
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 4071ff4ebd5a..e8bebb74bdd0 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -32,8 +32,10 @@ import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.InterruptedException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
import java.util.List;
/**
@@ -205,14 +207,42 @@ public class ResolverListController {
return listToReturn;
}
+ private class ComputeCallback implements ResolverComparator.AfterCompute {
+
+ private CountDownLatch mFinishComputeSignal;
+
+ public ComputeCallback(CountDownLatch finishComputeSignal) {
+ mFinishComputeSignal = finishComputeSignal;
+ }
+
+ public void afterCompute () {
+ mFinishComputeSignal.countDown();
+ }
+ }
+
@VisibleForTesting
@WorkerThread
public void sort(List<ResolverActivity.ResolvedComponentInfo> inputList) {
+ final CountDownLatch finishComputeSignal = new CountDownLatch(1);
+ ComputeCallback callback = new ComputeCallback(finishComputeSignal);
if (mResolverComparator == null) {
- mResolverComparator = new ResolverComparator(mContext, mTargetIntent, mReferrerPackage);
+ mResolverComparator =
+ new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, callback);
+ } else {
+ mResolverComparator.setCallBack(callback);
+ }
+ try {
+ long beforeRank = System.currentTimeMillis();
+ mResolverComparator.compute(inputList);
+ finishComputeSignal.await();
+ Collections.sort(inputList, mResolverComparator);
+ long afterRank = System.currentTimeMillis();
+ if (DEBUG) {
+ Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank));
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Compute & Sort was interrupted: " + e);
}
- mResolverComparator.compute(inputList);
- Collections.sort(inputList, mResolverComparator);
}
private static boolean isSameResolvedComponent(ResolveInfo a,
@@ -233,7 +263,7 @@ public class ResolverListController {
@VisibleForTesting
public float getScore(ResolverActivity.DisplayResolveInfo target) {
if (mResolverComparator == null) {
- mResolverComparator = new ResolverComparator(mContext, mTargetIntent, mReferrerPackage);
+ return 0.0f;
}
return mResolverComparator.getScore(target.getResolvedComponentName());
}
@@ -249,4 +279,10 @@ public class ResolverListController {
mResolverComparator.updateChooserCounts(packageName, userId, action);
}
}
+
+ public void destroy() {
+ if (mResolverComparator != null) {
+ mResolverComparator.destroy();
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 7ce5fc3103b6..b3904f457708 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -477,12 +477,9 @@ public class ToolbarActionBar extends ActionBar {
final KeyCharacterMap kmap = KeyCharacterMap.load(
event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
menu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC);
- menu.performShortcut(keyCode, event, 0);
+ return menu.performShortcut(keyCode, event, 0);
}
- // This action bar always returns true for handling keyboard shortcuts.
- // This will block the window from preparing a temporary panel to handle
- // keyboard shortcuts.
- return true;
+ return false;
}
@Override
@@ -525,6 +522,17 @@ public class ToolbarActionBar extends ActionBar {
}
return result;
}
+
+ @Override
+ public View onCreatePanelView(int featureId) {
+ if (featureId == Window.FEATURE_OPTIONS_PANEL) {
+ // This gets called by PhoneWindow.preparePanel. Since this already manages
+ // its own panel, we return a dummy view here to prevent PhoneWindow from
+ // preparing a default one.
+ return new View(mDecorToolbar.getContext());
+ }
+ return super.onCreatePanelView(featureId);
+ }
}
private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3d0d6bf0e3ad..a0dafddc623b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -10057,6 +10057,9 @@ public class BatteryStatsImpl extends BatteryStats {
public void setBatteryStateLocked(int status, int health, int plugType, int level,
int temp, int volt, int chargeUAh, int chargeFullUAh) {
+ // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
+ temp = Math.max(0, temp);
+
final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
final long uptime = mClocks.uptimeMillis();
final long elapsedRealtime = mClocks.elapsedRealtime();
diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java
index 3603b6df11da..8edd637ea814 100644
--- a/core/java/com/android/internal/os/FuseAppLoop.java
+++ b/core/java/com/android/internal/os/FuseAppLoop.java
@@ -19,16 +19,16 @@ package com.android.internal.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.ProxyFileDescriptorCallback;
+import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.OsConstants;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
-
-import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.ThreadFactory;
public class FuseAppLoop {
@@ -42,14 +42,21 @@ public class FuseAppLoop {
return new Thread(r, TAG);
}
};
+ private static final int FUSE_OK = 0;
private final Object mLock = new Object();
private final int mMountPointId;
private final Thread mThread;
+ private final Handler mDefaultHandler;
+
+ private static final int CMD_FSYNC = 1;
@GuardedBy("mLock")
private final SparseArray<CallbackEntry> mCallbackMap = new SparseArray<>();
+ @GuardedBy("mLock")
+ private final BytesMap mBytesMap = new BytesMap();
+
/**
* Sequential number can be used as file name and inode in AppFuse.
* 0 is regarded as an error, 1 is mount point. So we start the number from 2.
@@ -57,38 +64,40 @@ public class FuseAppLoop {
@GuardedBy("mLock")
private int mNextInode = MIN_INODE;
- private FuseAppLoop(
+ @GuardedBy("mLock")
+ private long mInstance;
+
+ public FuseAppLoop(
int mountPointId, @NonNull ParcelFileDescriptor fd, @Nullable ThreadFactory factory) {
mMountPointId = mountPointId;
- final int rawFd = fd.detachFd();
if (factory == null) {
factory = sDefaultThreadFactory;
}
- mThread = factory.newThread(new Runnable() {
- @Override
- public void run() {
- // rawFd is closed by native_start_loop. Java code does not need to close it.
- native_start_loop(rawFd);
+ mInstance = native_new(fd.detachFd());
+ mThread = factory.newThread(() -> {
+ native_start(mInstance);
+ synchronized (mLock) {
+ native_delete(mInstance);
+ mInstance = 0;
+ mBytesMap.clear();
}
});
+ mThread.start();
+ mDefaultHandler = null;
}
- public static @NonNull FuseAppLoop open(int mountPointId, @NonNull ParcelFileDescriptor fd,
- @Nullable ThreadFactory factory) {
- Preconditions.checkNotNull(fd);
- final FuseAppLoop loop = new FuseAppLoop(mountPointId, fd, factory);
- loop.mThread.start();
- return loop;
- }
-
- public int registerCallback(@NonNull ProxyFileDescriptorCallback callback)
- throws UnmountedException, IOException {
- if (mThread.getState() == Thread.State.TERMINATED) {
- throw new UnmountedException();
- }
+ public int registerCallback(@NonNull ProxyFileDescriptorCallback callback,
+ @NonNull Handler handler) throws FuseUnavailableMountException {
synchronized (mLock) {
- if (mCallbackMap.size() >= Integer.MAX_VALUE - MIN_INODE) {
- throw new IOException("Too many opened files.");
+ Preconditions.checkNotNull(callback);
+ Preconditions.checkNotNull(handler);
+ Preconditions.checkState(
+ mCallbackMap.size() < Integer.MAX_VALUE - MIN_INODE, "Too many opened files.");
+ Preconditions.checkArgument(
+ Thread.currentThread().getId() != handler.getLooper().getThread().getId(),
+ "Handler must be different from the current thread");
+ if (mInstance == 0) {
+ throw new FuseUnavailableMountException(mMountPointId);
}
int id;
while (true) {
@@ -101,118 +110,171 @@ public class FuseAppLoop {
break;
}
}
- mCallbackMap.put(id, new CallbackEntry(callback));
+ mCallbackMap.put(id, new CallbackEntry(callback, handler));
return id;
}
}
public void unregisterCallback(int id) {
- mCallbackMap.remove(id);
+ synchronized (mLock) {
+ mCallbackMap.remove(id);
+ }
}
public int getMountPointId() {
return mMountPointId;
}
- private CallbackEntry getCallbackEntryOrThrowLocked(long inode) throws ErrnoException {
- final CallbackEntry entry = mCallbackMap.get(checkInode(inode));
- if (entry != null) {
- return entry;
- } else {
- throw new ErrnoException("getCallbackEntry", OsConstants.ENOENT);
- }
- }
+ // Defined in fuse.h
+ private static final int FUSE_LOOKUP = 1;
+ private static final int FUSE_GETATTR = 3;
+ private static final int FUSE_OPEN = 14;
+ private static final int FUSE_READ = 15;
+ private static final int FUSE_WRITE = 16;
+ private static final int FUSE_RELEASE = 18;
+ private static final int FUSE_FSYNC = 20;
+
+ // Defined in FuseBuffer.h
+ private static final int FUSE_MAX_WRITE = 256 * 1024;
// Called by JNI.
@SuppressWarnings("unused")
- private long onGetSize(long inode) {
+ private void onCommand(int command, long unique, long inode, long offset, int size,
+ byte[] data) {
synchronized(mLock) {
try {
- return getCallbackEntryOrThrowLocked(inode).callback.onGetSize();
- } catch (ErrnoException exp) {
- return getError(exp);
+ final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode);
+ entry.postRunnable(() -> {
+ try {
+ switch (command) {
+ case FUSE_LOOKUP: {
+ final long fileSize = entry.callback.onGetSize();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyLookup(mInstance, unique, inode, fileSize);
+ }
+ }
+ break;
+ }
+ case FUSE_GETATTR: {
+ final long fileSize = entry.callback.onGetSize();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyGetAttr(mInstance, unique, inode, fileSize);
+ }
+ }
+ break;
+ }
+ case FUSE_READ:
+ final int readSize = entry.callback.onRead(offset, size, data);
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyRead(mInstance, unique, readSize, data);
+ }
+ }
+ break;
+ case FUSE_WRITE:
+ final int writeSize = entry.callback.onWrite(offset, size, data);
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyWrite(mInstance, unique, writeSize);
+ }
+ }
+ break;
+ case FUSE_FSYNC:
+ entry.callback.onFsync();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, FUSE_OK);
+ }
+ }
+ break;
+ case FUSE_RELEASE:
+ entry.callback.onRelease();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, FUSE_OK);
+ }
+ mBytesMap.stopUsing(entry.getThreadId());
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown FUSE command: " + command);
+ }
+ } catch (Exception error) {
+ Log.e(TAG, "", error);
+ replySimple(unique, getError(error));
+ }
+ });
+ } catch (ErrnoException error) {
+ Log.e(TAG, "", error);
+ replySimpleLocked(unique, getError(error));
}
}
}
// Called by JNI.
@SuppressWarnings("unused")
- private int onOpen(long inode) {
- synchronized(mLock) {
+ private byte[] onOpen(long unique, long inode) {
+ synchronized (mLock) {
try {
final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode);
if (entry.opened) {
throw new ErrnoException("onOpen", OsConstants.EMFILE);
}
- entry.opened = true;
- // Use inode as file handle. It's OK because AppFuse does not allow to open the same
- // file twice.
- return (int) inode;
- } catch (ErrnoException exp) {
- return getError(exp);
+ if (mInstance != 0) {
+ native_replyOpen(mInstance, unique, /* fh */ inode);
+ entry.opened = true;
+ return mBytesMap.startUsing(entry.getThreadId());
+ }
+ } catch (ErrnoException error) {
+ replySimpleLocked(unique, getError(error));
}
+ return null;
}
}
- // Called by JNI.
- @SuppressWarnings("unused")
- private int onFsync(long inode) {
- synchronized(mLock) {
- try {
- getCallbackEntryOrThrowLocked(inode).callback.onFsync();
- return 0;
- } catch (ErrnoException exp) {
- return getError(exp);
+ private static int getError(@NonNull Exception error) {
+ if (error instanceof ErrnoException) {
+ final int errno = ((ErrnoException) error).errno;
+ if (errno != OsConstants.ENOSYS) {
+ return -errno;
}
}
+ return -OsConstants.EBADF;
}
- // Called by JNI.
- @SuppressWarnings("unused")
- private int onRelease(long inode) {
- synchronized(mLock) {
- try {
- getCallbackEntryOrThrowLocked(inode).callback.onRelease();
- return 0;
- } catch (ErrnoException exp) {
- return getError(exp);
- } finally {
- mCallbackMap.remove(checkInode(inode));
- }
+ private CallbackEntry getCallbackEntryOrThrowLocked(long inode) throws ErrnoException {
+ final CallbackEntry entry = mCallbackMap.get(checkInode(inode));
+ if (entry == null) {
+ throw new ErrnoException("getCallbackEntryOrThrowLocked", OsConstants.ENOENT);
}
+ return entry;
}
- // Called by JNI.
- @SuppressWarnings("unused")
- private int onRead(long inode, long offset, int size, byte[] bytes) {
- synchronized(mLock) {
- try {
- return getCallbackEntryOrThrowLocked(inode).callback.onRead(offset, size, bytes);
- } catch (ErrnoException exp) {
- return getError(exp);
- }
+ private void replySimple(long unique, int result) {
+ synchronized (mLock) {
+ replySimpleLocked(unique, result);
}
}
- // Called by JNI.
- @SuppressWarnings("unused")
- private int onWrite(long inode, long offset, int size, byte[] bytes) {
- synchronized(mLock) {
- try {
- return getCallbackEntryOrThrowLocked(inode).callback.onWrite(offset, size, bytes);
- } catch (ErrnoException exp) {
- return getError(exp);
- }
+ private void replySimpleLocked(long unique, int result) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, result);
}
}
- private static int getError(@NonNull ErrnoException exp) {
- // Should not return ENOSYS because the kernel stops
- // dispatching the FUSE action once FUSE implementation returns ENOSYS for the action.
- return exp.errno != OsConstants.ENOSYS ? -exp.errno : -OsConstants.EIO;
- }
+ native long native_new(int fd);
+ native void native_delete(long ptr);
+ native void native_start(long ptr);
- native boolean native_start_loop(int fd);
+ native void native_replySimple(long ptr, long unique, int result);
+ native void native_replyOpen(long ptr, long unique, long fh);
+ native void native_replyLookup(long ptr, long unique, long inode, long size);
+ native void native_replyGetAttr(long ptr, long unique, long inode, long size);
+ native void native_replyWrite(long ptr, long unique, int size);
+ native void native_replyRead(long ptr, long unique, int size, byte[] bytes);
private static int checkInode(long inode) {
Preconditions.checkArgumentInRange(inode, MIN_INODE, Integer.MAX_VALUE, "checkInode");
@@ -223,10 +285,61 @@ public class FuseAppLoop {
private static class CallbackEntry {
final ProxyFileDescriptorCallback callback;
+ final Handler handler;
boolean opened;
- CallbackEntry(ProxyFileDescriptorCallback callback) {
- Preconditions.checkNotNull(callback);
- this.callback = callback;
+
+ CallbackEntry(ProxyFileDescriptorCallback callback, Handler handler) {
+ this.callback = Preconditions.checkNotNull(callback);
+ this.handler = Preconditions.checkNotNull(handler);
+ }
+
+ long getThreadId() {
+ return handler.getLooper().getThread().getId();
+ }
+
+ void postRunnable(Runnable runnable) throws ErrnoException {
+ final boolean result = handler.post(runnable);
+ if (!result) {
+ throw new ErrnoException("postRunnable", OsConstants.EBADF);
+ }
+ }
+ }
+
+ /**
+ * Entry for bytes map.
+ */
+ private static class BytesMapEntry {
+ int counter = 0;
+ byte[] bytes = new byte[FUSE_MAX_WRITE];
+ }
+
+ /**
+ * Map between Thread ID and byte buffer.
+ */
+ private static class BytesMap {
+ final Map<Long, BytesMapEntry> mEntries = new HashMap<>();
+
+ byte[] startUsing(long threadId) {
+ BytesMapEntry entry = mEntries.get(threadId);
+ if (entry == null) {
+ entry = new BytesMapEntry();
+ mEntries.put(threadId, entry);
+ }
+ entry.counter++;
+ return entry.bytes;
+ }
+
+ void stopUsing(long threadId) {
+ final BytesMapEntry entry = mEntries.get(threadId);
+ Preconditions.checkNotNull(entry);
+ entry.counter--;
+ if (entry.counter <= 0) {
+ mEntries.remove(threadId);
+ }
+ }
+
+ void clear() {
+ mEntries.clear();
}
}
}
diff --git a/media/java/android/media/UnsupportedCasException.java b/core/java/com/android/internal/os/FuseUnavailableMountException.java
index 31676373783b..ca3cfb90ae11 100644
--- a/media/java/android/media/UnsupportedCasException.java
+++ b/core/java/com/android/internal/os/FuseUnavailableMountException.java
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package android.media;
+package com.android.internal.os;
/**
- * Exception thrown when an attempt is made to construct a MediaCas object
- * using a CA_system_id that is not supported by the device
+ * Exception occurred when the mount point has already been unavailable.
*/
-public final class UnsupportedCasException extends MediaCasException {
- public UnsupportedCasException(String detailMessage) {
- super(detailMessage);
+public class FuseUnavailableMountException extends Exception {
+ public FuseUnavailableMountException(int mountId) {
+ super("AppFuse mount point " + mountId + " is unavailable");
}
}
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index f27c0d4df4ce..cc3f58cb0c3d 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -26,6 +26,7 @@ import android.util.Log;
import android.webkit.WebViewFactory;
import android.webkit.WebViewFactoryProvider;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -67,16 +68,20 @@ class WebViewZygoteInit {
}
@Override
- protected boolean handlePreloadPackage(String packagePath, String libsPath) {
+ protected boolean handlePreloadPackage(String packagePath, String libsPath,
+ String cacheKey) {
// Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
// our children will reuse the same classloader instead of creating their own.
// This enables us to preload Java and native code in the webview zygote process and
// have the preloaded versions actually be used post-fork.
ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader(
- packagePath, libsPath);
+ packagePath, libsPath, cacheKey);
// Add the APK to the Zygote's list of allowed files for children.
- Zygote.nativeAllowFileAcrossFork(packagePath);
+ String[] packageList = TextUtils.split(packagePath, File.pathSeparator);
+ for (String packageEntry : packageList) {
+ Zygote.nativeAllowFileAcrossFork(packageEntry);
+ }
// Once we have the classloader, look up the WebViewFactoryProvider implementation and
// call preloadInZygote() on it to give it the opportunity to preload the native library
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index e2485e90e537..a9bec4123fd2 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -177,7 +177,7 @@ class ZygoteConnection {
if (parsedArgs.preloadPackage != null) {
return handlePreloadPackage(parsedArgs.preloadPackage,
- parsedArgs.preloadPackageLibs);
+ parsedArgs.preloadPackageLibs, parsedArgs.preloadPackageCacheKey);
}
if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
@@ -314,7 +314,7 @@ class ZygoteConnection {
return ZygoteInit.isPreloadComplete();
}
- protected boolean handlePreloadPackage(String packagePath, String libsPath) {
+ protected boolean handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
throw new RuntimeException("Zyogte does not support package preloading");
}
@@ -428,6 +428,7 @@ class ZygoteConnection {
*/
String preloadPackage;
String preloadPackageLibs;
+ String preloadPackageCacheKey;
/**
* Whether this is a request to start preloading the default resources and classes.
@@ -599,6 +600,7 @@ class ZygoteConnection {
} else if (arg.equals("--preload-package")) {
preloadPackage = args[++curArg];
preloadPackageLibs = args[++curArg];
+ preloadPackageCacheKey = args[++curArg];
} else if (arg.equals("--preload-default")) {
preloadDefault = true;
} else {
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index d67cef3f0dda..8d9630fe5654 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -2070,8 +2070,6 @@ public class StateMachine {
* @param args
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- // Cannot just invoke pw.println(this.toString()) because if the
- // resulting string is to long it won't be displayed.
pw.println(getName() + ":");
pw.println(" total records=" + getLogRecCount());
for (int i = 0; i < getLogRecSize(); i++) {
@@ -2083,12 +2081,15 @@ public class StateMachine {
@Override
public String toString() {
- StringWriter sr = new StringWriter();
- PrintWriter pr = new PrintWriter(sr);
- dump(null, pr, null);
- pr.flush();
- pr.close();
- return sr.toString();
+ String name = "(null)";
+ String state = "(null)";
+ try {
+ name = mName.toString();
+ state = mSmHandler.getCurrentState().getName().toString();
+ } catch (NullPointerException npe) {
+ // Will use default(s) initialized above.
+ }
+ return "name=" + name + " state=" + state;
}
/**
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 6d814bf14bc0..d2a907222eda 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ReceiverCallNotAllowedException;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
@@ -86,24 +87,7 @@ public class SwipeDismissLayout extends FrameLayout {
private OnDismissedListener mDismissedListener;
private OnSwipeProgressChangedListener mProgressListener;
- private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
- private Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- if (mDismissed) {
- dismiss();
- } else {
- cancel();
- }
- resetMembers();
- }
- };
-
- @Override
- public void onReceive(Context context, Intent intent) {
- post(mRunnable);
- }
- };
+ private BroadcastReceiver mScreenOffReceiver;
private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
@@ -146,12 +130,36 @@ public class SwipeDismissLayout extends FrameLayout {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter);
+ try {
+ mScreenOffReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ post(() -> {
+ if (mDismissed) {
+ dismiss();
+ } else {
+ cancel();
+ }
+ resetMembers();
+ });
+ }
+ };
+ getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter);
+ } catch (ReceiverCallNotAllowedException e) {
+ /* Exception is thrown if the context is a ReceiverRestrictedContext object. As
+ * ReceiverRestrictedContext is not public, the context type cannot be checked before
+ * calling registerReceiver. The most likely scenario in which the exception would be
+ * thrown would be when a BroadcastReceiver creates a dialog to show the user. */
+ mScreenOffReceiver = null; // clear receiver since it was not used.
+ }
}
@Override
protected void onDetachedFromWindow() {
- getContext().unregisterReceiver(mScreenOffReceiver);
+ if (mScreenOffReceiver != null) {
+ getContext().unregisterReceiver(mScreenOffReceiver);
+ mScreenOffReceiver = null;
+ }
super.onDetachedFromWindow();
}
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index b6b1ac75f0e9..fcb72c2a869d 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -325,11 +325,12 @@ static jint convertProgramInfoFromNative(JNIEnv *env,
ALOGV("%s channel %d tuned %d", __FUNCTION__, nProgramInfo->channel, nProgramInfo->tuned);
+ int flags = 0; // TODO(b/32621193): pass from the HAL
*jProgramInfo = env->NewObject(gRadioProgramInfoClass, gRadioProgramInfoCstor,
nProgramInfo->channel, nProgramInfo->sub_channel,
nProgramInfo->tuned, nProgramInfo->stereo,
nProgramInfo->digital, nProgramInfo->signal_strength,
- jMetadata);
+ jMetadata, flags);
env->DeleteLocalRef(jMetadata);
return (jint)RADIO_STATUS_OK;
@@ -932,7 +933,7 @@ int register_android_hardware_Radio(JNIEnv *env)
jclass programInfoClass = FindClassOrDie(env, kRadioProgramInfoClassPathName);
gRadioProgramInfoClass = MakeGlobalRefOrDie(env, programInfoClass);
gRadioProgramInfoCstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
- "(IIZZZILandroid/hardware/radio/RadioMetadata;)V");
+ "(IIZZZILandroid/hardware/radio/RadioMetadata;I)V");
jclass metadataClass = FindClassOrDie(env, kRadioMetadataClassPathName);
gRadioMetadataClass = MakeGlobalRefOrDie(env, metadataClass);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 713287e4cd7a..8a7d1cf9c12f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -135,6 +135,7 @@ int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f) {
case PublicFormat::DEPTH16:
return HAL_PIXEL_FORMAT_Y16;
case PublicFormat::RAW_SENSOR:
+ case PublicFormat::RAW_DEPTH:
return HAL_PIXEL_FORMAT_RAW16;
default:
// Most formats map 1:1
@@ -149,6 +150,7 @@ android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
return HAL_DATASPACE_V0_JFIF;
case PublicFormat::DEPTH_POINT_CLOUD:
case PublicFormat::DEPTH16:
+ case PublicFormat::RAW_DEPTH:
return HAL_DATASPACE_DEPTH;
case PublicFormat::RAW_SENSOR:
case PublicFormat::RAW_PRIVATE:
@@ -182,8 +184,12 @@ PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
// Enums overlap in both name and value
return static_cast<PublicFormat>(format);
case HAL_PIXEL_FORMAT_RAW16:
- // Name differs, though value is the same
- return PublicFormat::RAW_SENSOR;
+ switch (dataSpace) {
+ case HAL_DATASPACE_DEPTH:
+ return PublicFormat::RAW_DEPTH;
+ default:
+ return PublicFormat::RAW_SENSOR;
+ }
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
// Name differs, though value is the same
return PublicFormat::RAW_PRIVATE;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 6fbf49bfee8c..066ce68e7e57 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -167,7 +167,7 @@ static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
buffer->getHeight(),
buffer->getPixelFormat(),
buffer->getUsage(),
- (void*)buffer.get());
+ (jlong)buffer.get());
}
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
diff --git a/core/jni/com_android_internal_os_FuseAppLoop.cpp b/core/jni/com_android_internal_os_FuseAppLoop.cpp
index dd003eb364c5..e125150e8329 100644
--- a/core/jni/com_android_internal_os_FuseAppLoop.cpp
+++ b/core/jni/com_android_internal_os_FuseAppLoop.cpp
@@ -20,140 +20,214 @@
#include <stdlib.h>
#include <sys/stat.h>
+#include <map>
+#include <memory>
+
#include <android_runtime/Log.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <jni.h>
#include <libappfuse/FuseAppLoop.h>
#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
#include "core_jni_helpers.h"
namespace android {
-
namespace {
-
constexpr const char* CLASS_NAME = "com/android/internal/os/FuseAppLoop";
jclass gFuseAppLoopClass;
-jmethodID gOnGetSizeMethod;
+jmethodID gOnCommandMethod;
jmethodID gOnOpenMethod;
-jmethodID gOnFsyncMethod;
-jmethodID gOnReleaseMethod;
-jmethodID gOnReadMethod;
-jmethodID gOnWriteMethod;
class Callback : public fuse::FuseAppLoopCallback {
private:
- static constexpr size_t kBufferSize = std::max(fuse::kFuseMaxWrite, fuse::kFuseMaxRead);
- static_assert(kBufferSize <= INT32_MAX, "kBufferSize should be fit in int32_t.");
-
+ typedef ScopedLocalRef<jbyteArray> LocalBytes;
JNIEnv* const mEnv;
jobject const mSelf;
- ScopedLocalRef<jbyteArray> mJniBuffer;
-
- template <typename T>
- T checkException(T result) const {
- if (mEnv->ExceptionCheck()) {
- LOGE_EX(mEnv, nullptr);
- mEnv->ExceptionClear();
- return -EIO;
- }
- return result;
- }
+ std::map<uint64_t, std::unique_ptr<LocalBytes>> mBuffers;
public:
Callback(JNIEnv* env, jobject self) :
- mEnv(env),
- mSelf(self),
- mJniBuffer(env, nullptr) {}
+ mEnv(env), mSelf(self) {}
- bool Init() {
- mJniBuffer.reset(mEnv->NewByteArray(kBufferSize));
- return mJniBuffer.get();
+ void OnLookup(uint64_t unique, uint64_t inode) override {
+ mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_LOOKUP, unique, inode, 0, 0, nullptr);
+ CHECK(!mEnv->ExceptionCheck());
}
- bool IsActive() override {
- return true;
+ void OnGetAttr(uint64_t unique, uint64_t inode) override {
+ mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_GETATTR, unique, inode, 0, 0, nullptr);
+ CHECK(!mEnv->ExceptionCheck());
}
- int64_t OnGetSize(uint64_t inode) override {
- return checkException(mEnv->CallLongMethod(mSelf, gOnGetSizeMethod, inode));
- }
+ void OnOpen(uint64_t unique, uint64_t inode) override {
+ const jbyteArray buffer = static_cast<jbyteArray>(mEnv->CallObjectMethod(
+ mSelf, gOnOpenMethod, unique, inode));
+ CHECK(!mEnv->ExceptionCheck());
+ if (buffer == nullptr) {
+ return;
+ }
- int32_t OnOpen(uint64_t inode) override {
- return checkException(mEnv->CallIntMethod(mSelf, gOnOpenMethod, inode));
+ mBuffers.insert(std::make_pair(inode, std::unique_ptr<LocalBytes>(
+ new LocalBytes(mEnv, buffer))));
}
- int32_t OnFsync(uint64_t inode) override {
- return checkException(mEnv->CallIntMethod(mSelf, gOnFsyncMethod, inode));
+ void OnFsync(uint64_t unique, uint64_t inode) override {
+ mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_FSYNC, unique, inode, 0, 0, nullptr);
+ CHECK(!mEnv->ExceptionCheck());
}
- int32_t OnRelease(uint64_t inode) override {
- return checkException(mEnv->CallIntMethod(mSelf, gOnReleaseMethod, inode));
+ void OnRelease(uint64_t unique, uint64_t inode) override {
+ mBuffers.erase(inode);
+ mEnv->CallVoidMethod(mSelf, gOnCommandMethod, FUSE_RELEASE, unique, inode, 0, 0, nullptr);
+ CHECK(!mEnv->ExceptionCheck());
}
- int32_t OnRead(uint64_t inode, uint64_t offset, uint32_t size, void* buffer) override {
- CHECK_LE(size, static_cast<uint32_t>(kBufferSize));
- const int32_t result = checkException(mEnv->CallIntMethod(
- mSelf, gOnReadMethod, inode, offset, size, mJniBuffer.get()));
- if (result <= 0) {
- return result;
- }
- if (result > static_cast<int32_t>(size)) {
- LOG(ERROR) << "Returned size is too large.";
- return -EIO;
- }
+ void OnRead(uint64_t unique, uint64_t inode, uint64_t offset, uint32_t size) override {
+ CHECK_LE(size, static_cast<uint32_t>(fuse::kFuseMaxRead));
- mEnv->GetByteArrayRegion(mJniBuffer.get(), 0, result, static_cast<jbyte*>(buffer));
- CHECK(!mEnv->ExceptionCheck());
+ auto it = mBuffers.find(inode);
+ CHECK(it != mBuffers.end());
- return checkException(result);
+ mEnv->CallVoidMethod(
+ mSelf, gOnCommandMethod, FUSE_READ, unique, inode, offset, size,
+ it->second->get());
+ CHECK(!mEnv->ExceptionCheck());
}
- int32_t OnWrite(uint64_t inode, uint64_t offset, uint32_t size, const void* buffer) override {
- CHECK_LE(size, static_cast<uint32_t>(kBufferSize));
+ void OnWrite(uint64_t unique, uint64_t inode, uint64_t offset, uint32_t size,
+ const void* buffer) override {
+ CHECK_LE(size, static_cast<uint32_t>(fuse::kFuseMaxWrite));
+
+ auto it = mBuffers.find(inode);
+ CHECK(it != mBuffers.end());
+
+ jbyteArray const javaBuffer = it->second->get();
- mEnv->SetByteArrayRegion(mJniBuffer.get(), 0, size, static_cast<const jbyte*>(buffer));
+ mEnv->SetByteArrayRegion(javaBuffer, 0, size, static_cast<const jbyte*>(buffer));
CHECK(!mEnv->ExceptionCheck());
- return checkException(mEnv->CallIntMethod(
- mSelf, gOnWriteMethod, inode, offset, size, mJniBuffer.get()));
+ mEnv->CallVoidMethod(
+ mSelf, gOnCommandMethod, FUSE_WRITE, unique, inode, offset, size, javaBuffer);
+ CHECK(!mEnv->ExceptionCheck());
}
};
-jboolean com_android_internal_os_FuseAppLoop_start_loop(JNIEnv* env, jobject self, jint jfd) {
- base::unique_fd fd(jfd);
+jlong com_android_internal_os_FuseAppLoop_new(JNIEnv* env, jobject self, jint jfd) {
+ return reinterpret_cast<jlong>(new fuse::FuseAppLoop(base::unique_fd(jfd)));
+}
+
+void com_android_internal_os_FuseAppLoop_delete(JNIEnv* env, jobject self, jlong ptr) {
+ delete reinterpret_cast<fuse::FuseAppLoop*>(ptr);
+}
+
+void com_android_internal_os_FuseAppLoop_start(JNIEnv* env, jobject self, jlong ptr) {
Callback callback(env, self);
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Start(&callback);
+}
- if (!callback.Init()) {
- LOG(ERROR) << "Failed to init callback";
- return JNI_FALSE;
+void com_android_internal_os_FuseAppLoop_replySimple(
+ JNIEnv* env, jobject self, jlong ptr, jlong unique, jint result) {
+ if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplySimple(unique, result)) {
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
}
+}
- return fuse::StartFuseAppLoop(fd.release(), &callback);
+void com_android_internal_os_FuseAppLoop_replyOpen(
+ JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong fh) {
+ if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyOpen(unique, fh)) {
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
+ }
+}
+
+void com_android_internal_os_FuseAppLoop_replyLookup(
+ JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) {
+ if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyLookup(unique, inode, size)) {
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
+ }
+}
+
+void com_android_internal_os_FuseAppLoop_replyGetAttr(
+ JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) {
+ if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyGetAttr(
+ unique, inode, size, S_IFREG | 0777)) {
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
+ }
+}
+
+void com_android_internal_os_FuseAppLoop_replyWrite(
+ JNIEnv* env, jobject self, jlong ptr, jlong unique, jint size) {
+ if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyWrite(unique, size)) {
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
+ }
+}
+
+void com_android_internal_os_FuseAppLoop_replyRead(
+ JNIEnv* env, jobject self, jlong ptr, jlong unique, jint size, jbyteArray data) {
+ ScopedByteArrayRO array(env, data);
+ CHECK(size >= 0);
+ CHECK(static_cast<size_t>(size) < array.size());
+ if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyRead(unique, size, array.get())) {
+ reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
+ }
}
const JNINativeMethod methods[] = {
{
- "native_start_loop",
- "(I)Z",
- (void *) com_android_internal_os_FuseAppLoop_start_loop
- }
+ "native_new",
+ "(I)J",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_new)
+ },
+ {
+ "native_delete",
+ "(J)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_delete)
+ },
+ {
+ "native_start",
+ "(J)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_start)
+ },
+ {
+ "native_replySimple",
+ "(JJI)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replySimple)
+ },
+ {
+ "native_replyOpen",
+ "(JJJ)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyOpen)
+ },
+ {
+ "native_replyLookup",
+ "(JJJJ)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyLookup)
+ },
+ {
+ "native_replyGetAttr",
+ "(JJJJ)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyGetAttr)
+ },
+ {
+ "native_replyRead",
+ "(JJI[B)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyRead)
+ },
+ {
+ "native_replyWrite",
+ "(JJI)V",
+ reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyWrite)
+ },
};
-
} // namespace
int register_com_android_internal_os_FuseAppLoop(JNIEnv* env) {
gFuseAppLoopClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, CLASS_NAME));
- gOnGetSizeMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onGetSize", "(J)J");
- gOnOpenMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onOpen", "(J)I");
- gOnFsyncMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onFsync", "(J)I");
- gOnReleaseMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onRelease", "(J)I");
- gOnReadMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onRead", "(JJI[B)I");
- gOnWriteMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onWrite", "(JJI[B)I");
+ gOnCommandMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onCommand", "(IJJJI[B)V");
+ gOnOpenMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onOpen", "(JJ)[B");
RegisterMethodsOrDie(env, CLASS_NAME, methods, NELEM(methods));
return 0;
}
-
} // namespace android
diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h
index 3f1bdff81aef..d27c5a354677 100644
--- a/core/jni/include/android_runtime/android_view_Surface.h
+++ b/core/jni/include/android_runtime/android_view_Surface.h
@@ -53,6 +53,7 @@ enum class PublicFormat {
RGBA_1010102 = 0x2b,
JPEG = 0x100,
DEPTH_POINT_CLOUD = 0x101,
+ RAW_DEPTH = 0x1002, // @hide
YV12 = 0x32315659,
Y8 = 0x20203859, // @hide
Y16 = 0x20363159, // @hide
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8721f3414e4b..3dc8890c2de2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -313,6 +313,10 @@
<protected-broadcast android:name="android.net.wifi.STATE_CHANGE" />
<protected-broadcast android:name="android.net.wifi.LINK_CONFIGURATION_CHANGED" />
<protected-broadcast android:name="android.net.wifi.CONFIGURED_NETWORKS_CHANGE" />
+ <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT" />
+ <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_ICON" />
+ <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST" />
+ <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION" />
<protected-broadcast android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
<protected-broadcast android:name="android.net.wifi.supplicant.STATE_CHANGE" />
<protected-broadcast android:name="android.net.wifi.p2p.STATE_CHANGED" />
@@ -440,6 +444,7 @@
<protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED" />
<protected-broadcast android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" />
<protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" />
<protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
<protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />
@@ -1346,7 +1351,7 @@
<permission android:name="android.permission.CONNECTIVITY_INTERNAL"
android:protectionLevel="signature|privileged" />
- <!-- Allows an internal user to use restricted Networks.
+ <!-- @SystemApi Allows an internal user to use restricted Networks.
@hide -->
<permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"
android:protectionLevel="signature|privileged" />
@@ -2312,6 +2317,10 @@
<permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA"
android:protectionLevel="signature" />
+ <!-- @hide Allows an application to change the accessibility volume. -->
+ <permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME"
+ android:protectionLevel="signature" />
+
<!-- @hide Allows an application to collect frame statistics -->
<permission android:name="android.permission.FRAME_STATS"
android:protectionLevel="signature" />
@@ -3120,6 +3129,15 @@
<permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
android:protectionLevel="signature" />
+ <!-- @SystemApi Must be required by services that extend
+ {@link android.service.resolver.ResolverRankerService}, to ensure that only the system can
+ bind to them.
+ <p>Protection level: signature
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Must be required by a {@link
android.service.notification.ConditionProviderService},
to ensure that only the system can bind to it.
@@ -3625,6 +3643,14 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
+ <service android:name="com.android.internal.app.LRResolverRankerService"
+ android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"
+ android:exported="false"
+ android:priority="-1" >
+ <intent-filter>
+ <action android:name="android.service.resolver.ResolverRankerService" />
+ </intent-filter>
+ </service>
</application>
</manifest>
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index edcbb2b6b498..4c1d6cb53539 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -35,6 +35,7 @@ This is an optimized layout for a screen with the Action Bar enabled.
android:layout_alignParentTop="true"
style="?attr/actionBarStyle"
android:transitionName="android:action_bar"
+ android:touchscreenBlocksFocus="true"
android:keyboardNavigationCluster="true"
android:gravity="top">
<com.android.internal.widget.ActionBarView
@@ -54,6 +55,7 @@ This is an optimized layout for a screen with the Action Bar enabled.
android:layout_height="wrap_content"
style="?attr/actionBarSplitStyle"
android:visibility="gone"
+ android:touchscreenBlocksFocus="true"
android:keyboardNavigationCluster="true"
android:gravity="center"/>
</com.android.internal.widget.ActionBarOverlayLayout>
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
index 0bec8c40c1a8..ded252798441 100644
--- a/core/res/res/layout/screen_toolbar.xml
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -35,6 +35,7 @@ This is an optimized layout for a screen with a toolbar enabled.
android:layout_alignParentTop="true"
style="?attr/actionBarStyle"
android:transitionName="android:action_bar"
+ android:touchscreenBlocksFocus="true"
android:keyboardNavigationCluster="true"
android:gravity="top">
<Toolbar
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 995f2c3b8356..a3b27052bf67 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7226,6 +7226,10 @@
<!-- Whether to use single line for the preference title text. By default, preference title
will be constrained to one line, so the default value of this attribute is true. -->
<attr name="singleLineTitle" format="boolean" />
+ <!-- Whether the space for the preference icon view will be reserved. By default, preference
+ icon view visibility will be set to GONE when there is no icon provided, so the default
+ value of this attribute is false. -->
+ <attr name="iconSpaceReserved" format="boolean" />
</declare-styleable>
<!-- Base attributes available to CheckBoxPreference. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 68e766e46279..194c119f076c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1880,8 +1880,16 @@
Takes effect only if the scrollbar drawables have no intrinsic size. -->
<dimen name="config_scrollbarSize">4dp</dimen>
- <!-- Distance that should be scrolled in response to a {@link MotionEvent#ACTION_SCROLL event}
- with an axis value of 1. -->
+ <!-- Distance that should be scrolled, per axis value, in response to a horizontal
+ {@link MotionEvent#ACTION_SCROLL} event. -->
+ <dimen name="config_horizontalScrollFactor">64dp</dimen>
+
+ <!-- Distance that should be scrolled, per axis value, in response to a vertical
+ {@link MotionEvent#ACTION_SCROLL} event. -->
+ <dimen name="config_verticalScrollFactor">64dp</dimen>
+
+ <!-- Obsolete. Distance that should be scrolled, per axis value, in response to a
+ {@link MotionEvent#ACTION_SCROLL} event. -->
<dimen name="config_scrollFactor">64dp</dimen>
<!-- Maximum number of grid columns permitted in the ResolverActivity
@@ -2580,12 +2588,14 @@
<integer name="config_defaultPictureInPictureGravity">0x55</integer>
<!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture. Any
- ratio smaller than this is considered too tall and thin to be usable. -->
- <item name="config_pictureInPictureMinAspectRatio" format="float" type="dimen">0.5</item>
+ ratio smaller than this is considered too tall and thin to be usable. Currently, this
+ is the inverse of the max landscape aspect ratio (1:2.39), but this is an extremely
+ skinny aspect ratio that is not expected to be widely used. -->
+ <item name="config_pictureInPictureMinAspectRatio" format="float" type="dimen">0.41841004184</item>
<!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture. Any
- ratio larger than this is considered to wide and short to be usable. -->
- <item name="config_pictureInPictureMaxAspectRatio" format="float" type="dimen">2.35</item>
+ ratio larger than this is considered to wide and short to be usable. Currently 2.39:1. -->
+ <item name="config_pictureInPictureMaxAspectRatio" format="float" type="dimen">2.39</item>
<!-- The snap mode to use for picture-in-picture. These values correspond to constants defined
in PipSnapAlgorithm and should not be changed independently.
@@ -2799,4 +2809,9 @@
<!-- Colon separated list of package names that should be granted Notification Listener access -->
<string name="config_defaultListenerAccessPackages" translatable="false"></string>
+
+ <!-- Maximum size, specified in pixels, to restrain the display space width to. Height and
+ density will be scaled accordingly to maintain aspect ratio. A value of 0 indicates no
+ constraint will be enforced. -->
+ <integer name="config_maxUiWidth">0</integer>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 876d44da416b..6e20208cc2d6 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2813,6 +2813,7 @@
<public name="iconTint" />
<public name="iconTintMode" />
<public name="maxAspectRatio"/>
+ <public name="iconSpaceReserved"/>
</public-group>
<public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 868e256496bb..4afa8dcdfb4a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -189,22 +189,23 @@
<!-- Displayed to tell the user that they cannot change the caller ID setting. -->
<string name="CLIRPermanent">You can\'t change the caller ID setting.</string>
- <!-- Displayed to tell the user that data service is blocked by access control. -->
- <string name="RestrictedOnData">Data service is blocked.</string>
- <!-- Displayed to tell the user that emergency service is blocked by access control. -->
- <string name="RestrictedOnEmergency">Emergency service is blocked.</string>
- <!-- Displayed to tell the user that normal service is blocked by access control. -->
- <string name="RestrictedOnNormal">Voice service is blocked.</string>
- <!-- Displayed to tell the user that all emergency and normal voice services are blocked by access control. -->
- <string name="RestrictedOnAllVoice">All voice services are blocked.</string>
- <!-- Displayed to tell the user that sms service is blocked by access control. -->
- <string name="RestrictedOnSms">SMS service is blocked.</string>
- <!-- Displayed to tell the user that voice/data service is blocked by access control. -->
- <string name="RestrictedOnVoiceData">Voice/data services are blocked.</string>
- <!-- Displayed to tell the user that voice and sms service are blocked by access control. -->
- <string name="RestrictedOnVoiceSms">Voice/SMS services are blocked.</string>
- <!-- Displayed to tell the user that all service is blocked by access control. -->
- <string name="RestrictedOnAll">All voice/data/SMS services are blocked.</string>
+ <!-- Notification title to tell the user that data service is blocked by access control. -->
+ <string name="RestrictedOnDataTitle">No data service</string>
+ <!-- Notification title to tell the user that emergency service is blocked by access control. -->
+ <string name="RestrictedOnEmergencyTitle">No emergency service</string>
+ <!-- Notification title to tell the user that normal service is blocked by access control. -->
+ <string name="RestrictedOnNormalTitle">No voice service</string>
+ <!-- Notification title to tell the user that all emergency and normal voice services are blocked by access control. -->
+ <string name="RestrictedOnAllVoiceTitle">No voice/emergency service</string>
+
+ <!-- Notification content to tell the user that data service is blocked by access control. -->
+ <string name="RestrictedOnDataContent">Your carrier has temporarily suspended data service at this location</string>
+ <!-- Notification content to tell the user that emergency service is blocked by access control. -->
+ <string name="RestrictedOnEmergencyContent">Your carrier has temporarily suspended emergency calls at this location</string>
+ <!-- Notification content to tell the user that normal service is blocked by access control. -->
+ <string name="RestrictedOnNormalContent">Your carrier has temporarily suspended voice calls at this location</string>
+ <!-- Notification content to tell the user that all emergency and normal voice services are blocked by access control. -->
+ <string name="RestrictedOnAllVoiceContent">Your carrier has temporarily suspended voice and emergency calls at this location</string>
<!-- Displayed to tell the user that they should switch their network preference. -->
<string name="NetworkPreferenceSwitchTitle">Can\u2019t reach network</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 25873d2f8fd7..7dac18dbda8d 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1249,6 +1249,7 @@ please see styles_device_defaults.xml.
<item name="collapseContentDescription">@string/toolbar_collapse_description</item>
<item name="contentInsetStart">16dp</item>
<item name="contentInsetStartWithNavigation">@dimen/action_bar_content_inset_with_nav</item>
+ <item name="touchscreenBlocksFocus">true</item>
<item name="keyboardNavigationCluster">true</item>
</style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b23c96c9b05f..24be0b04a047 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -434,6 +434,8 @@
<java-symbol type="dimen" name="config_viewMinFlingVelocity" />
<java-symbol type="dimen" name="config_viewMaxFlingVelocity" />
<java-symbol type="dimen" name="config_scrollbarSize" />
+ <java-symbol type="dimen" name="config_horizontalScrollFactor" />
+ <java-symbol type="dimen" name="config_verticalScrollFactor" />
<java-symbol type="dimen" name="config_scrollFactor" />
<java-symbol type="dimen" name="default_app_widget_padding_bottom" />
<java-symbol type="dimen" name="default_app_widget_padding_left" />
@@ -507,12 +509,16 @@
<java-symbol type="string" name="Noon" />
<java-symbol type="string" name="PinMmi" />
<java-symbol type="string" name="PwdMmi" />
- <java-symbol type="string" name="RestrictedOnAllVoice" />
- <java-symbol type="string" name="RestrictedOnData" />
- <java-symbol type="string" name="RestrictedOnEmergency" />
- <java-symbol type="string" name="RestrictedOnNormal" />
<java-symbol type="string" name="NetworkPreferenceSwitchSummary" />
<java-symbol type="string" name="NetworkPreferenceSwitchTitle" />
+ <java-symbol type="string" name="RestrictedOnAllVoiceTitle" />
+ <java-symbol type="string" name="RestrictedOnDataTitle" />
+ <java-symbol type="string" name="RestrictedOnEmergencyTitle" />
+ <java-symbol type="string" name="RestrictedOnNormalTitle" />
+ <java-symbol type="string" name="RestrictedOnAllVoiceContent" />
+ <java-symbol type="string" name="RestrictedOnDataContent" />
+ <java-symbol type="string" name="RestrictedOnEmergencyContent" />
+ <java-symbol type="string" name="RestrictedOnNormalContent" />
<java-symbol type="string" name="SetupCallDefault" />
<java-symbol type="string" name="accept" />
<java-symbol type="string" name="activity_chooser_view_see_all" />
@@ -2919,6 +2925,9 @@
<!-- Colon separated list of package names that should be granted Notification Listener access -->
<java-symbol type="string" name="config_defaultListenerAccessPackages" />
+ <!-- maximum width of the display -->
+ <java-symbol type="integer" name="config_maxUiWidth" />
+
<!-- system notification channels -->
<java-symbol type="string" name="notification_channel_virtual_keyboard" />
<java-symbol type="string" name="notification_channel_physical_keyboard" />
diff --git a/core/tests/coretests/README b/core/tests/coretests/README
index 4a6984320e61..aced4417ba02 100644
--- a/core/tests/coretests/README
+++ b/core/tests/coretests/README
@@ -45,6 +45,10 @@ To run tests in debug mode:
-e debug true
+To uninstall the package:
+
+ adb shell pm uninstall -k com.android.frameworks.coretests
+
For more arguments, see the guide to command=line testing:
https://developer.android.com/studio/test/command-line.html
diff --git a/core/tests/coretests/src/android/content/ContentTests.java b/core/tests/coretests/src/android/content/ContentTests.java
index a1299e3a0e8d..567b79a674c1 100644
--- a/core/tests/coretests/src/android/content/ContentTests.java
+++ b/core/tests/coretests/src/android/content/ContentTests.java
@@ -23,6 +23,7 @@ public class ContentTests {
TestSuite suite = new TestSuite(ContentTests.class.getName());
suite.addTestSuite(AssetTest.class);
+ suite.addTestSuite(ContentValuesTest.class);
return suite;
}
}
diff --git a/core/tests/coretests/src/android/content/ContentValuesTest.java b/core/tests/coretests/src/android/content/ContentValuesTest.java
new file mode 100644
index 000000000000..7b39939b2d0c
--- /dev/null
+++ b/core/tests/coretests/src/android/content/ContentValuesTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+
+/*
+ runtest -c android.content.ContentValuesTest frameworks-core
+
+ or
+
+ make -j256 FrameworksCoreTests && \
+ adb shell pm uninstall -k com.android.frameworks.coretests && \
+ adb install out/target/product/bullhead/testcases/FrameworksCoreTests/FrameworksCoreTests.apk && \
+ adb shell am instrument -w -e package android.content \
+ com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+*/
+public class ContentValuesTest extends AndroidTestCase {
+
+ @SmallTest
+ public void testIsEmpty() throws Exception {
+ ContentValues cv = new ContentValues();
+ assertTrue(cv.isEmpty());
+ assertEquals(0, cv.size());
+
+ cv.put("key", "value");
+ assertFalse(cv.isEmpty());
+ assertEquals(1, cv.size());
+ }
+}
diff --git a/core/tests/coretests/src/android/database/PageViewCursorTest.java b/core/tests/coretests/src/android/database/PageViewCursorTest.java
index 62b54105cf9a..fba6aaf3f406 100644
--- a/core/tests/coretests/src/android/database/PageViewCursorTest.java
+++ b/core/tests/coretests/src/android/database/PageViewCursorTest.java
@@ -13,20 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.database;
+import static com.android.internal.util.ArrayUtils.contains;
+import static com.android.internal.util.Preconditions.checkArgument;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.annotation.Nullable;
import android.content.ContentResolver;
+import android.os.Build;
import android.os.Bundle;
import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.util.MathUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
import java.util.Random;
@RunWith(AndroidJUnit4.class)
@@ -37,32 +45,32 @@ public class PageViewCursorTest {
private static final String NAME_COLUMN = "name";
private static final String NUM_COLUMN = "num";
- private static final String[] COLUMNS = new String[]{
- NAME_COLUMN,
- NUM_COLUMN
+ private static final String[] COLUMNS = new String[] {
+ NAME_COLUMN,
+ NUM_COLUMN
};
private static final String[] NAMES = new String[] {
- "000",
- "111",
- "222",
- "333",
- "444",
- "555",
- "666",
- "777",
- "888",
- "999",
- "aaa",
- "bbb",
- "ccc",
- "ddd",
- "eee",
- "fff",
- "ggg",
- "hhh",
- "iii",
- "jjj"
+ "000",
+ "111",
+ "222",
+ "333",
+ "444",
+ "555",
+ "666",
+ "777",
+ "888",
+ "999",
+ "aaa",
+ "bbb",
+ "ccc",
+ "ddd",
+ "eee",
+ "fff",
+ "ggg",
+ "hhh",
+ "iii",
+ "jjj"
};
private MatrixCursor mDelegate;
@@ -79,7 +87,7 @@ public class PageViewCursorTest {
row.add(NUM_COLUMN, rand.nextInt());
}
- mCursor = new PageViewCursor(mDelegate, 10, 5);
+ mCursor = new PageViewCursor(mDelegate, createArgs(10, 5));
}
@Test
@@ -94,7 +102,7 @@ public class PageViewCursorTest {
@Test
public void testPage_OffsetExceedsCursorCount_EffectivelyEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, ITEM_COUNT * 2, 5);
+ mCursor = new PageViewCursor(mDelegate, createArgs(ITEM_COUNT * 2, 5));
assertEquals(0, mCursor.getCount());
}
@@ -155,13 +163,13 @@ public class PageViewCursorTest {
@Test
public void testCount_ZeroForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, 0, 0);
+ mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
assertEquals(0, mCursor.getCount());
}
@Test
public void testIsBeforeFirst_TrueForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, 0, 0);
+ mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
assertTrue(mCursor.isBeforeFirst());
}
@@ -175,7 +183,7 @@ public class PageViewCursorTest {
@Test
public void testIsAfterLast_TrueForEmptyCursor() {
- mCursor = new PageViewCursor(mDelegate, 0, 0);
+ mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
assertTrue(mCursor.isAfterLast());
}
@@ -247,71 +255,131 @@ public class PageViewCursorTest {
}
@Test
- public void testOffset_LimitOutOfBounds() {
- mCursor = new PageViewCursor(mDelegate, 5, 100);
+ public void testLimitOutOfBounds() {
+ mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
assertEquals(15, mCursor.getCount());
}
@Test
- public void testAutoPagedExtra() {
- mCursor = new PageViewCursor(mDelegate, 5, 100);
+ public void testOffsetOutOfBounds_EmptyResult() {
+ mCursor = new PageViewCursor(mDelegate, createArgs(100000, 100));
+ assertEquals(0, mCursor.getCount());
+ }
+
+ @Test
+ public void testAddsExtras() {
+ mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
assertTrue(mCursor.getExtras().getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
+ String[] honoredArgs = mCursor.getExtras()
+ .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
+ assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
+ assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
+ }
+
+ @Test
+ public void testAddsExtras_OnlyOffset() {
+ Bundle args = new Bundle();
+ args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
+ mCursor = new PageViewCursor(mDelegate, args);
+ String[] honoredArgs = mCursor.getExtras()
+ .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
+ assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
+ assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
+ }
+
+ @Test
+ public void testAddsExtras_OnlyLimit() {
+ Bundle args = new Bundle();
+ args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
+ mCursor = new PageViewCursor(mDelegate, args);
+ String[] honoredArgs = mCursor.getExtras()
+ .getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
+ assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
+ assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
}
@Test
public void testGetWindow() {
- mCursor = new PageViewCursor(mDelegate, 5, 5);
+ mCursor = new PageViewCursor(mDelegate, createArgs(5, 5));
CursorWindow window = mCursor.getWindow();
assertEquals(5, window.getNumRows());
}
@Test
- public void testWrap() {
- Bundle queryArgs = new Bundle();
- queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, queryArgs);
+ public void testWraps() {
+ Bundle args = createArgs(5, 5);
+ Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
assertTrue(wrapped instanceof PageViewCursor);
assertEquals(5, wrapped.getCount());
}
@Test
- public void testWrap_NoOpWithoutPagingArgs() {
+ public void testWraps_NullExtras() {
+ Bundle args = createArgs(5, 5);
+ mDelegate.setExtras(null);
+ Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
+ assertTrue(wrapped instanceof PageViewCursor);
+ assertEquals(5, wrapped.getCount());
+ }
+
+ @Test
+ public void testWraps_WithJustOffset() {
+ Bundle args = new Bundle();
+ args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
+ Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
+ assertTrue(wrapped instanceof PageViewCursor);
+ assertEquals(15, wrapped.getCount());
+ }
+
+ @Test
+ public void testWraps_WithJustLimit() {
+ Bundle args = new Bundle();
+ args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
+ Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
+ assertTrue(wrapped instanceof PageViewCursor);
+ assertEquals(5, wrapped.getCount());
+ }
+
+ @Test
+ public void testNoWrap_WithoutPagingArgs() {
Cursor wrapped = PageViewCursor.wrap(mDelegate, Bundle.EMPTY);
assertTrue(mDelegate == wrapped);
}
@Test
- public void testWrap_NoOpCursorsWithExistingPaging_ByTotalSize() {
+ public void testNoWrap_CursorsHasExistingPaging_ByTotalSize() {
Bundle extras = new Bundle();
extras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, 5);
mDelegate.setExtras(extras);
- Bundle queryArgs = new Bundle();
- queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, queryArgs);
+ Bundle args = createArgs(5, 5);
+ Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
assertTrue(mDelegate == wrapped);
}
@Test
- public void testWrap_NoOpCursorsWithExistingPaging_ByHonoredArgs() {
+ public void testNoWrap_CursorsHasExistingPaging_ByHonoredArgs() {
Bundle extras = new Bundle();
extras.putStringArray(
ContentResolver.EXTRA_HONORED_ARGS,
new String[] {
- ContentResolver.QUERY_ARG_OFFSET,
- ContentResolver.QUERY_ARG_LIMIT
+ ContentResolver.QUERY_ARG_OFFSET,
+ ContentResolver.QUERY_ARG_LIMIT
});
mDelegate.setExtras(extras);
- Bundle queryArgs = new Bundle();
- queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
- queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
- Cursor wrapped = PageViewCursor.wrap(mDelegate, queryArgs);
+ Bundle args = createArgs(5, 5);
+ Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
assertTrue(mDelegate == wrapped);
}
+ private static Bundle createArgs(int offset, int limit) {
+ Bundle args = new Bundle();
+ args.putInt(ContentResolver.QUERY_ARG_OFFSET, offset);
+ args.putInt(ContentResolver.QUERY_ARG_LIMIT, limit);
+ return args;
+ }
+
private void assertStringAt(int row, int column, String expected) {
mCursor.moveToPosition(row);
assertEquals(expected, mCursor.getString(column));
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
index ff98eb763f76..fbba6fffcd8e 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
@@ -264,7 +264,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
final MyThreadFactory factory = new MyThreadFactory();
int firstMountId;
try (final ParcelFileDescriptor fd = mSm.openProxyFileDescriptor(
- ParcelFileDescriptor.MODE_READ_ONLY, callback, factory)) {
+ ParcelFileDescriptor.MODE_READ_ONLY, callback, null, factory)) {
assertNotSame(Thread.State.TERMINATED, factory.thread.getState());
firstMountId = mSm.getProxyFileDescriptorMountPointId();
assertNotSame(-1, firstMountId);
@@ -276,7 +276,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
// StorageManager should mount another bridge on the next open request.
try (final ParcelFileDescriptor fd = mSm.openProxyFileDescriptor(
- ParcelFileDescriptor.MODE_WRITE_ONLY, callback, factory)) {
+ ParcelFileDescriptor.MODE_WRITE_ONLY, callback, null, factory)) {
assertNotSame(Thread.State.TERMINATED, factory.thread.getState());
assertNotSame(firstMountId, mSm.getProxyFileDescriptorMountPointId());
}
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index 3fbf169460b2..108585dc0886 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -349,7 +349,6 @@ public class SettingsProviderTest extends AndroidTestCase {
assertCanBeHandled(new Intent(Settings.ACTION_USER_DICTIONARY_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_WIFI_IP_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS));
- assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SAVED_NETWORK_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
diff --git a/core/tests/utiltests/runtests.sh b/core/tests/utiltests/runtests.sh
new file mode 100755
index 000000000000..853119f62334
--- /dev/null
+++ b/core/tests/utiltests/runtests.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+ echo "You need to source and lunch before you can use this script"
+ exit 1
+fi
+
+echo "Running tests"
+
+set -e # fail early
+
+echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/core/tests/utiltests"
+# NOTE Don't actually run the command above since this shell doesn't inherit functions from the
+# caller.
+make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-base-core-tests-utiltests
+
+set -x # print commands
+
+adb root
+adb wait-for-device
+
+adb install -r -g "$OUT/data/app/FrameworksUtilTests/FrameworksUtilTests.apk"
+
+adb shell am instrument -w "$@" 'com.android.frameworks.utiltests/android.support.test.runner.AndroidJUnitRunner'
diff --git a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
index d29b5723065b..eb2a5165dc4f 100644
--- a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
@@ -80,6 +80,66 @@ public class StateMachineTest extends TestCase {
}
/**
+ * Tests {@link StateMachine#toString()}.
+ */
+ class StateMachineToStringTest extends StateMachine {
+ StateMachineToStringTest(String name) {
+ super(name);
+ }
+ }
+
+ class ExampleState extends State {
+ String mName;
+
+ ExampleState(String name) {
+ mName = name;
+ }
+
+ @Override
+ public String getName() {
+ return mName;
+ }
+ }
+
+ @SmallTest
+ public void testToStringSucceedsEvenIfMachineHasNoStates() throws Exception {
+ StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine");
+ assertTrue(stateMachine.toString().contains("TestStateMachine"));
+ }
+
+ @SmallTest
+ public void testToStringSucceedsEvenIfStateHasNoName() throws Exception {
+ StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine");
+ State exampleState = new ExampleState(null);
+ stateMachine.addState(exampleState);
+ stateMachine.setInitialState(exampleState);
+ stateMachine.start();
+ assertTrue(stateMachine.toString().contains("TestStateMachine"));
+ assertTrue(stateMachine.toString().contains("(null)"));
+ }
+
+ @SmallTest
+ public void testToStringIncludesMachineAndStateNames() throws Exception {
+ StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine");
+ State exampleState = new ExampleState("exampleState");
+ stateMachine.addState(exampleState);
+ stateMachine.setInitialState(exampleState);
+ stateMachine.start();
+ assertTrue(stateMachine.toString().contains("TestStateMachine"));
+ assertTrue(stateMachine.toString().contains("exampleState"));
+ }
+
+ @SmallTest
+ public void testToStringDoesNotContainMultipleLines() throws Exception {
+ StateMachine stateMachine = new StateMachineToStringTest("TestStateMachine");
+ State exampleState = new ExampleState("exampleState");
+ stateMachine.addState(exampleState);
+ stateMachine.setInitialState(exampleState);
+ stateMachine.start();
+ assertFalse(stateMachine.toString().contains("\n"));
+ }
+
+ /**
* Tests {@link StateMachine#quit()}.
*/
class StateMachineQuitTest extends StateMachine {
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 344f3c83ba6c..5e3488c1ed42 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -181,6 +181,10 @@
<allow-in-power-save package="com.android.cellbroadcastreceiver" />
<allow-in-power-save package="com.android.shell" />
+ <!-- Package in charge of provisioning that needs to freely run in the background -->
+ <!-- STOPSHIP: Revert this once it is fixed properly -->
+ <allow-in-power-save package="com.android.managedprovisioning" />
+
<!-- These are the packages that are white-listed to be able to run as system user -->
<system-user-whitelisted-app package="com.android.settings" />
diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java
index 33d19d4063f5..d69f67d138a1 100644
--- a/graphics/java/android/graphics/Color.java
+++ b/graphics/java/android/graphics/Color.java
@@ -22,6 +22,7 @@ import android.annotation.ColorLong;
import android.annotation.HalfFloat;
import android.annotation.IntRange;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.Size;
import android.util.Half;
@@ -288,7 +289,7 @@ import java.util.function.DoubleUnaryOperator;
* and <code>(1.0, 0.0, 0.0, 0.5)</code>.</p>
*/
@AnyThread
-public class Color {
+public final class Color {
@ColorInt public static final int BLACK = 0xFF000000;
@ColorInt public static final int DKGRAY = 0xFF444444;
@ColorInt public static final int GRAY = 0xFF888888;
@@ -415,7 +416,7 @@ public class Color {
* to this color space's color model, plus one extra component for
* alpha.
*
- * @return An integer between 4 and 5
+ * @return The integer 4 or 5
*/
@IntRange(from = 4, to = 5)
public int getComponentCount() {
@@ -560,7 +561,37 @@ public class Color {
@NonNull
@Size(min = 4, max = 5)
public float[] getComponents() {
- return Arrays.copyOf(mComponents, mColorSpace.getComponentCount() + 1);
+ return Arrays.copyOf(mComponents, mComponents.length);
+ }
+
+ /**
+ * Copies this color's components in the supplied array. The last element of the
+ * array is always the alpha component.
+ *
+ * @param components An array of floats whose size must be at least
+ * {@link #getComponentCount()}, can be null
+ * @return The array passed as a parameter if not null, or a new array of length
+ * {@link #getComponentCount()}
+ *
+ * @see #getComponent(int)
+ *
+ * @throws IllegalArgumentException If the specified array's length is less than
+ * {@link #getComponentCount()}
+ */
+ @NonNull
+ @Size(min = 4)
+ public float[] getComponents(@Nullable @Size(min = 4) float[] components) {
+ if (components == null) {
+ return Arrays.copyOf(mComponents, mComponents.length);
+ }
+
+ if (components.length < mComponents.length) {
+ throw new IllegalArgumentException("The specified array's length must be at "
+ + "least " + mComponents.length);
+ }
+
+ System.arraycopy(mComponents, 0, components, 0, mComponents.length);
+ return components;
}
/**
@@ -570,7 +601,7 @@ public class Color {
*
* <p>If the requested component index is {@link #getComponentCount()},
* this method returns the alpha component, always in the range
- * \([0..1\).</p>
+ * \([0..1]\).</p>
*
* @see #getComponents()
*
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index b78df34f5c3e..ff9f11dae4dc 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -189,9 +189,8 @@ public class FontListParser {
skip(parser);
}
}
- String fullFilename = "/system/fonts/" +
- FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
- return new FontConfig.Font(fullFilename, index,
+ String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
+ return new FontConfig.Font(sanitizedName, index,
axes.toArray(new FontConfig.Axis[axes.size()]), weight, isItalic);
}
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index a226e85618e8..e3527e359d62 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -662,6 +662,15 @@ public class ImageFormat {
public static final int DEPTH_POINT_CLOUD = 0x101;
/**
+ * Unprocessed implementation-dependent raw
+ * depth measurements, opaque with 16 bit
+ * samples.
+ *
+ * @hide
+ */
+ public static final int RAW_DEPTH = 0x1002;
+
+ /**
* Android private opaque image format.
* <p>
* The choices of the actual format and pixel data layout are entirely up to
@@ -723,6 +732,7 @@ public class ImageFormat {
return 24;
case FLEX_RGBA_8888:
return 32;
+ case RAW_DEPTH:
case RAW_SENSOR:
return 16;
case RAW10:
@@ -765,6 +775,7 @@ public class ImageFormat {
case DEPTH16:
case DEPTH_POINT_CLOUD:
case PRIVATE:
+ case RAW_DEPTH:
return true;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 228d9500180a..8c3a2e8068ca 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -1003,21 +1003,22 @@ public class Typeface {
Map<String, ByteBuffer> bufferForPath) {
FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
for (FontConfig.Font font : family.getFonts()) {
- ByteBuffer fontBuffer = bufferForPath.get(font.getFontName());
+ String fullPathName = "/system/fonts/" + font.getFontName();
+ ByteBuffer fontBuffer = bufferForPath.get(fullPathName);
if (fontBuffer == null) {
- try (FileInputStream file = new FileInputStream(font.getFontName())) {
+ try (FileInputStream file = new FileInputStream(fullPathName)) {
FileChannel fileChannel = file.getChannel();
long fontSize = fileChannel.size();
fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
- bufferForPath.put(font.getFontName(), fontBuffer);
+ bufferForPath.put(fullPathName, fontBuffer);
} catch (IOException e) {
- Log.e(TAG, "Error mapping font file " + font.getFontName());
+ Log.e(TAG, "Error mapping font file " + fullPathName);
continue;
}
}
if (!fontFamily.addFontFromBuffer(fontBuffer, font.getTtcIndex(), font.getAxes(),
font.getWeight(), font.isItalic() ? Builder.ITALIC : Builder.NORMAL)) {
- Log.e(TAG, "Error creating font " + font.getFontName() + "#" + font.getTtcIndex());
+ Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex());
}
}
fontFamily.freeze();
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 621d8c0e96f0..bd7b80469ddc 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -416,7 +416,9 @@ std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) {
ATRACE_CALL();
std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()};
- const ResTable_package* header = chunk.header<ResTable_package>();
+ constexpr size_t kMinPackageSize =
+ sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset);
+ const ResTable_package* header = chunk.header<ResTable_package, kMinPackageSize>();
if (header == nullptr) {
LOG(ERROR) << "Chunk RES_TABLE_PACKAGE_TYPE is too small.";
return {};
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index ec8d63ecde98..fde0e4760d61 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -50,6 +50,7 @@ hwui_src_files := \
service/GraphicsStatsService.cpp \
thread/TaskManager.cpp \
utils/Blur.cpp \
+ utils/Color.cpp \
utils/GLUtils.cpp \
utils/LinearAllocator.cpp \
utils/StringUtils.cpp \
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index e8972aab9f8f..d154730058ee 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -363,6 +363,7 @@ void BakedOpRenderer::renderFunctor(const FunctorOp& op, const BakedOpState& sta
state.computedState.transform.copyTo(&info.transform[0]);
mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info);
+ if (!mRenderTarget.frameBufferId) mHasDrawn = true;
}
void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) {
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
index 20aaf4a35ac1..c4f7fe2a56b8 100644
--- a/libs/hwui/GlLayer.h
+++ b/libs/hwui/GlLayer.h
@@ -44,7 +44,7 @@ public:
}
void setSize(uint32_t width, uint32_t height) override {
- texture.updateSize(width, height, texture.internalFormat(), texture.format(),
+ texture.updateLayout(width, height, texture.internalFormat(), texture.format(),
texture.target());
}
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 5cf52c69f0fd..3e7a246bb281 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -605,7 +605,11 @@ void GlopBuilder::build() {
} else {
mDescription.hasExternalTexture = true;
}
- mDescription.hasLinearTexture = mOutGlop->fill.texture.texture->isLinear();
+ Texture* texture = mOutGlop->fill.texture.texture;
+ mDescription.hasLinearTexture = texture->isLinear();
+ mDescription.hasColorSpaceConversion = texture->hasColorSpaceConversion();
+ mDescription.transferFunction = texture->getTransferFunctionType();
+ mDescription.hasTranslucentConversion = texture->blend;
}
mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Color;
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 7be71eec4f76..8126d57a3a79 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -264,10 +264,15 @@ void JankTracker::addFrame(const FrameInfo& frame) {
// the actual time spent blocked.
nsecs_t forgiveAmount = std::min(expectedDequeueDuration,
frame[FrameInfoIndex::DequeueBufferDuration]);
+ LOG_ALWAYS_FATAL_IF(forgiveAmount >= totalDuration,
+ "Impossible dequeue duration! dequeue duration reported %" PRId64
+ ", total duration %" PRId64, forgiveAmount, totalDuration);
totalDuration -= forgiveAmount;
}
}
+ LOG_ALWAYS_FATAL_IF(totalDuration <= 0, "Impossible totalDuration %" PRId64, totalDuration);
uint32_t framebucket = frameCountIndexForFrameTime(totalDuration);
+ LOG_ALWAYS_FATAL_IF(framebucket < 0, "framebucket < 0 (%u)", framebucket);
// Keep the fast path as fast as possible.
if (CC_LIKELY(totalDuration < mFrameInterval)) {
mData->frameCounts[framebucket]++;
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 5c8f8e93fa3d..2becfcb709c3 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -28,6 +28,7 @@
#include "FloatColor.h"
#include "Matrix.h"
#include "Properties.h"
+#include "utils/Color.h"
namespace android {
namespace uirenderer {
@@ -56,11 +57,11 @@ namespace uirenderer {
#define PROGRAM_KEY_BITMAP_NPOT 0x80
#define PROGRAM_KEY_BITMAP_EXTERNAL 0x100
-#define PROGRAM_KEY_SWAP_SRC_DST 0x2000
-
#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
+#define PROGRAM_KEY_SWAP_SRC_DST_SHIFT 13
+
// Encode the xfermodes on 6 bits
#define PROGRAM_MAX_XFERMODE 0x1f
#define PROGRAM_XFERMODE_SHADER_SHIFT 26
@@ -89,6 +90,10 @@ namespace uirenderer {
#define PROGRAM_HAS_GAMMA_CORRECTION 44
#define PROGRAM_HAS_LINEAR_TEXTURE 45
+#define PROGRAM_HAS_COLOR_SPACE_CONVERSION 46
+#define PROGRAM_TRANSFER_FUNCTION 47 // 2 bits for transfer function
+#define PROGRAM_HAS_TRANSLUCENT_CONVERSION 49
+
///////////////////////////////////////////////////////////////////////////////
// Types
///////////////////////////////////////////////////////////////////////////////
@@ -105,13 +110,13 @@ typedef uint64_t programid;
* A ProgramDescription must be used in conjunction with a ProgramCache.
*/
struct ProgramDescription {
- enum class ColorFilterMode {
+ enum class ColorFilterMode : int8_t {
None = 0,
Matrix,
Blend
};
- enum Gradient {
+ enum Gradient : int8_t {
kGradientLinear = 0,
kGradientCircular,
kGradientSweep
@@ -168,6 +173,11 @@ struct ProgramDescription {
// Set when sampling an image in linear space
bool hasLinearTexture;
+ bool hasColorSpaceConversion;
+ TransferFunctionType transferFunction;
+ // Indicates whether the bitmap to convert between color spaces is translucent
+ bool hasTranslucentConversion;
+
/**
* Resets this description. All fields are reset back to the default
* values they hold after building a new instance.
@@ -210,6 +220,10 @@ struct ProgramDescription {
hasGammaCorrection = false;
hasLinearTexture = false;
+
+ hasColorSpaceConversion = false;
+ transferFunction = TransferFunctionType::None;
+ hasTranslucentConversion = false;
}
/**
@@ -263,24 +277,27 @@ struct ProgramDescription {
break;
case ColorFilterMode::Blend:
key |= PROGRAM_KEY_COLOR_BLEND;
- key |= ((int)colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
+ key |= ((int) colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
break;
case ColorFilterMode::None:
break;
}
- key |= ((int)framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
- if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
- if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
- if (hasVertexAlpha) key |= programid(0x1) << PROGRAM_HAS_VERTEX_ALPHA_SHIFT;
- if (useShadowAlphaInterp) key |= programid(0x1) << PROGRAM_USE_SHADOW_ALPHA_INTERP_SHIFT;
- if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
- if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
- if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
- if (hasColors) key |= programid(0x1) << PROGRAM_HAS_COLORS;
- if (hasDebugHighlight) key |= programid(0x1) << PROGRAM_HAS_DEBUG_HIGHLIGHT;
- if (hasRoundRectClip) key |= programid(0x1) << PROGRAM_HAS_ROUND_RECT_CLIP;
- if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
- if (hasLinearTexture) key |= programid(0x1) << PROGRAM_HAS_LINEAR_TEXTURE;
+ key |= ((int) framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
+ key |= programid(swapSrcDst) << PROGRAM_KEY_SWAP_SRC_DST_SHIFT;
+ key |= programid(modulate) << PROGRAM_MODULATE_SHIFT;
+ key |= programid(hasVertexAlpha) << PROGRAM_HAS_VERTEX_ALPHA_SHIFT;
+ key |= programid(useShadowAlphaInterp) << PROGRAM_USE_SHADOW_ALPHA_INTERP_SHIFT;
+ key |= programid(hasExternalTexture) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
+ key |= programid(hasTextureTransform) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
+ key |= programid(isSimpleGradient) << PROGRAM_IS_SIMPLE_GRADIENT;
+ key |= programid(hasColors) << PROGRAM_HAS_COLORS;
+ key |= programid(hasDebugHighlight) << PROGRAM_HAS_DEBUG_HIGHLIGHT;
+ key |= programid(hasRoundRectClip) << PROGRAM_HAS_ROUND_RECT_CLIP;
+ key |= programid(hasGammaCorrection) << PROGRAM_HAS_GAMMA_CORRECTION;
+ key |= programid(hasLinearTexture) << PROGRAM_HAS_LINEAR_TEXTURE;
+ key |= programid(hasColorSpaceConversion) << PROGRAM_HAS_COLOR_SPACE_CONVERSION;
+ key |= programid(transferFunction) << PROGRAM_TRANSFER_FUNCTION;
+ key |= programid(hasTranslucentConversion) << PROGRAM_HAS_TRANSLUCENT_CONVERSION;
return key;
}
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 38c23e4babe8..1f78e09b5a58 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -161,17 +161,61 @@ const char* gFS_Uniforms_HasRoundRectClip =
"uniform vec4 roundRectInnerRectLTRB;\n"
"uniform float roundRectRadius;\n";
+const char* gFS_Uniforms_ColorSpaceConversion =
+ // TODO: Should we use a 3D LUT to combine the matrix and transfer functions?
+ // 32x32x32 fp16 LUTs (for scRGB output) are large and heavy to generate...
+ "uniform mat3 colorSpaceMatrix;\n";
+
+const char* gFS_Uniforms_TransferFunction[4] = {
+ // In this order: g, a, b, c, d, e, f
+ // See ColorSpace::TransferParameters
+ // We'll use hardware sRGB conversion as much as possible
+ "",
+ "uniform float transferFunction[7];\n",
+ "uniform float transferFunction[5];\n",
+ "uniform float transferFunctionGamma;\n"
+};
+
const char* gFS_OETF[2] = {
- "\nvec4 OETF(const vec4 linear) {\n"
- " return linear;\n"
- "}\n",
- // We expect linear data to be scRGB so we mirror the gamma function
- "\nvec4 OETF(const vec4 linear) {"
- " return vec4(sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)), linear.a);\n"
- "}\n",
+ R"__SHADER__(
+ vec4 OETF(const vec4 linear) {
+ return linear;
+ }
+ )__SHADER__",
+ // We expect linear data to be scRGB so we mirror the gamma function
+ R"__SHADER__(
+ vec4 OETF(const vec4 linear) {
+ return vec4(sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)), linear.a);
+ }
+ )__SHADER__"
+};
+
+const char* gFS_ColorConvert[3] = {
+ // Just OETF
+ R"__SHADER__(
+ vec4 colorConvert(const vec4 color) {
+ return OETF(color);
+ }
+ )__SHADER__",
+ // Full color conversion for opaque bitmaps
+ R"__SHADER__(
+ vec4 colorConvert(const vec4 color) {
+ return OETF(vec4(colorSpaceMatrix * EOTF_Parametric(color.rgb), color.a));
+ }
+ )__SHADER__",
+ // Full color conversion for translucent bitmaps
+ // Note: 0.5/256=0.0019
+ R"__SHADER__(
+ vec4 colorConvert(in vec4 color) {
+ color.rgb /= color.a + 0.0019;
+ color = OETF(vec4(colorSpaceMatrix * EOTF_Parametric(color.rgb), color.a));
+ color.rgb *= color.a + 0.0019;
+ return color;
+ }
+ )__SHADER__",
};
-const char* gFS_Transfer_Functions = R"__SHADER__(
+const char* gFS_sRGB_TransferFunctions = R"__SHADER__(
float OETF_sRGB(const float linear) {
// IEC 61966-2-1:1999
return linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1.0 / 2.4) * 1.055) - 0.055;
@@ -187,12 +231,56 @@ const char* gFS_Transfer_Functions = R"__SHADER__(
}
)__SHADER__";
+const char* gFS_TransferFunction[4] = {
+ // Conversion done by the texture unit (sRGB)
+ R"__SHADER__(
+ vec3 EOTF_Parametric(const vec3 x) {
+ return x;
+ }
+ )__SHADER__",
+ // Full transfer function
+ // TODO: We should probably use a 1D LUT (256x1 with texelFetch() since input is 8 bit)
+ // TODO: That would cause 3 dependent texture fetches. Is it worth it?
+ R"__SHADER__(
+ float EOTF_Parametric(float x) {
+ return x <= transferFunction[4]
+ ? transferFunction[3] * x + transferFunction[6]
+ : pow(transferFunction[1] * x + transferFunction[2], transferFunction[0])
+ + transferFunction[5];
+ }
+
+ vec3 EOTF_Parametric(const vec3 x) {
+ return vec3(EOTF_Parametric(x.r), EOTF_Parametric(x.g), EOTF_Parametric(x.b));
+ }
+ )__SHADER__",
+ // Limited transfer function, e = f = 0.0
+ R"__SHADER__(
+ float EOTF_Parametric(float x) {
+ return x <= transferFunction[4]
+ ? transferFunction[3] * x
+ : pow(transferFunction[1] * x + transferFunction[2], transferFunction[0]);
+ }
+
+ vec3 EOTF_Parametric(const vec3 x) {
+ return vec3(EOTF_Parametric(x.r), EOTF_Parametric(x.g), EOTF_Parametric(x.b));
+ }
+ )__SHADER__",
+ // Gamma transfer function, e = f = 0.0
+ R"__SHADER__(
+ vec3 EOTF_Parametric(const vec3 x) {
+ return vec3(pow(x.r, transferFunctionGamma),
+ pow(x.g, transferFunctionGamma),
+ pow(x.b, transferFunctionGamma));
+ }
+ )__SHADER__"
+};
+
// Dithering must be done in the quantization space
// When we are writing to an sRGB framebuffer, we must do the following:
// EOTF(OETF(color) + dither)
// The dithering pattern is generated with a triangle noise generator in the range [-1.0,1.0]
// TODO: Handle linear fp16 render targets
-const char* gFS_Gradient_Functions = R"__SHADER__(
+const char* gFS_GradientFunctions = R"__SHADER__(
float triangleNoise(const highp vec2 n) {
highp vec2 p = fract(n * vec2(5.3987, 5.4421));
p += dot(p.yx, p.xy + vec2(21.5351, 14.3137));
@@ -200,7 +288,8 @@ const char* gFS_Gradient_Functions = R"__SHADER__(
return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
}
)__SHADER__";
-const char* gFS_Gradient_Preamble[2] = {
+
+const char* gFS_GradientPreamble[2] = {
// Linear framebuffer
R"__SHADER__(
vec4 dither(const vec4 color) {
@@ -259,9 +348,9 @@ const char* gFS_Main_ApplyVertexAlphaShadowInterp =
" fragColor *= texture2D(baseSampler, vec2(alpha, 0.5)).a;\n";
const char* gFS_Main_FetchTexture[2] = {
// Don't modulate
- " fragColor = OETF(texture2D(baseSampler, outTexCoords));\n",
+ " fragColor = colorConvert(texture2D(baseSampler, outTexCoords));\n",
// Modulate
- " fragColor = color * texture2D(baseSampler, outTexCoords);\n"
+ " fragColor = color * colorConvert(texture2D(baseSampler, outTexCoords));\n"
};
const char* gFS_Main_FetchA8Texture[4] = {
// Don't modulate
@@ -290,9 +379,9 @@ const char* gFS_Main_FetchGradient[6] = {
" vec4 gradientColor = gradientMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
};
const char* gFS_Main_FetchBitmap =
- " vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n";
+ " vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, outBitmapTexCoords));\n";
const char* gFS_Main_FetchBitmapNpot =
- " vec4 bitmapColor = OETF(texture2D(bitmapSampler, wrap(outBitmapTexCoords)));\n";
+ " vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, wrap(outBitmapTexCoords)));\n";
const char* gFS_Main_BlendShadersBG =
" fragColor = blendShaders(gradientColor, bitmapColor)";
const char* gFS_Main_BlendShadersGB =
@@ -627,6 +716,11 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
}
shader.append(gFS_Uniforms_ColorOp[static_cast<int>(description.colorOp)]);
+ if (description.hasColorSpaceConversion) {
+ shader.append(gFS_Uniforms_ColorSpaceConversion);
+ }
+ shader.append(gFS_Uniforms_TransferFunction[static_cast<int>(description.transferFunction)]);
+
// Generate required functions
if (description.hasGradient && description.hasBitmap) {
generateBlend(shader, "blendShaders", description.shadersMode);
@@ -640,16 +734,21 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.useShaderBasedWrap) {
generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT);
}
- if (description.hasGradient || description.hasLinearTexture) {
- shader.append(gFS_Transfer_Functions);
+ if (description.hasGradient || description.hasLinearTexture
+ || description.hasColorSpaceConversion) {
+ shader.append(gFS_sRGB_TransferFunctions);
}
if (description.hasBitmap || ((description.hasTexture || description.hasExternalTexture) &&
!description.hasAlpha8Texture)) {
- shader.append(gFS_OETF[description.hasLinearTexture && !mHasLinearBlending]);
+ shader.append(gFS_TransferFunction[static_cast<int>(description.transferFunction)]);
+ shader.append(gFS_OETF[(description.hasLinearTexture || description.hasColorSpaceConversion)
+ && !mHasLinearBlending]);
+ shader.append(gFS_ColorConvert[description.hasColorSpaceConversion
+ ? 1 + description.hasTranslucentConversion : 0]);
}
if (description.hasGradient) {
- shader.append(gFS_Gradient_Functions);
- shader.append(gFS_Gradient_Preamble[mHasLinearBlending]);
+ shader.append(gFS_GradientFunctions);
+ shader.append(gFS_GradientPreamble[mHasLinearBlending]);
}
// Begin the shader
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 4f7f9d7f9b9a..8a504d4431c4 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -216,8 +216,13 @@ bool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& model
const float width = outData->bitmapTexture->width();
const float height = outData->bitmapTexture->height();
+ Texture* texture = outData->bitmapTexture;
+
description->hasBitmap = true;
- description->hasLinearTexture = outData->bitmapTexture->isLinear();
+ description->hasLinearTexture = texture->isLinear();
+ description->hasColorSpaceConversion = texture->hasColorSpaceConversion();
+ description->transferFunction = texture->getTransferFunctionType();
+ description->hasTranslucentConversion = texture->blend;
description->isShaderBitmapExternal = hwuiBitmap->isHardware();
// gralloc doesn't support non-clamp modes
if (hwuiBitmap->isHardware() || (!caches.extensions().hasNPot()
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index cfc2744e61b2..8b71086e1625 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -17,10 +17,13 @@
#include "Caches.h"
#include "Texture.h"
#include "utils/GLUtils.h"
+#include "utils/MathUtils.h"
#include "utils/TraceUtils.h"
#include <utils/Log.h>
+#include <math/mat4.h>
+
#include <SkCanvas.h>
namespace android {
@@ -48,12 +51,7 @@ static int bytesPerPixel(GLint glFormat) {
}
}
-bool Texture::isLinear() const {
- return mInternalFormat == GL_RGBA16F;
-}
-
void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force) {
-
if (force || wrapS != mWrapS || wrapT != mWrapT) {
mWrapS = wrapS;
mWrapT = wrapT;
@@ -94,7 +92,7 @@ void Texture::deleteTexture() {
}
}
-bool Texture::updateSize(uint32_t width, uint32_t height, GLint internalFormat,
+bool Texture::updateLayout(uint32_t width, uint32_t height, GLint internalFormat,
GLint format, GLenum target) {
if (mWidth == width
&& mHeight == height
@@ -122,7 +120,7 @@ void Texture::resetCachedParams() {
void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height,
GLenum format, GLenum type, const void* pixels) {
GL_CHECKPOINT(MODERATE);
- bool needsAlloc = updateSize(width, height, internalFormat, format, GL_TEXTURE_2D);
+ bool needsAlloc = updateLayout(width, height, internalFormat, format, GL_TEXTURE_2D);
if (!mId) {
glGenTextures(1, &mId);
needsAlloc = true;
@@ -224,7 +222,6 @@ void Texture::colorTypeToGlFormatAndType(const Caches& caches, SkColorType color
*outType = GL_UNSIGNED_BYTE;
break;
case kGray_8_SkColorType:
- // TODO: Handle sRGB
*outFormat = GL_LUMINANCE;
*outInternalFormat = GL_LUMINANCE;
*outType = GL_UNSIGNED_BYTE;
@@ -252,15 +249,14 @@ SkBitmap Texture::uploadToN32(const SkBitmap& bitmap, bool hasLinearBlending,
return rgbaBitmap;
}
-bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending,
- SkColorSpace* sRGB) {
- bool needSRGB = info.colorSpace() == sRGB;
+bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending) {
return info.colorType() == kARGB_4444_SkColorType
|| info.colorType() == kIndex_8_SkColorType
- || (info.colorType() == kRGB_565_SkColorType && hasLinearBlending && needSRGB);
+ || (info.colorType() == kRGB_565_SkColorType
+ && hasLinearBlending
+ && info.colorSpace()->isSRGB());
}
-
void Texture::upload(Bitmap& bitmap) {
if (!bitmap.readyToDraw()) {
ALOGE("Cannot generate texture from bitmap");
@@ -284,23 +280,59 @@ void Texture::upload(Bitmap& bitmap) {
setDefaultParams = true;
}
- sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
- bool needSRGB = bitmap.info().colorSpace() == sRGB.get();
+ bool hasLinearBlending = mCaches.extensions().hasLinearBlending();
+ bool needSRGB = transferFunctionCloseToSRGB(bitmap.info().colorSpace());
GLint internalFormat, format, type;
- colorTypeToGlFormatAndType(mCaches, bitmap.colorType(), needSRGB, &internalFormat, &format, &type);
+ colorTypeToGlFormatAndType(mCaches, bitmap.colorType(),
+ needSRGB && hasLinearBlending, &internalFormat, &format, &type);
+
+ mConnector.reset();
+
+ // RGBA16F is always extended sRGB, alpha masks don't have color profiles
+ if (internalFormat != GL_RGBA16F && internalFormat != GL_ALPHA) {
+ SkColorSpace* colorSpace = bitmap.info().colorSpace();
+ // If the bitmap is sRGB we don't need conversion
+ if (colorSpace != nullptr && !colorSpace->isSRGB()) {
+ SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor);
+ if (!colorSpace->toXYZD50(&xyzMatrix)) {
+ ALOGW("Incompatible color space!");
+ } else {
+ SkColorSpaceTransferFn fn;
+ if (!colorSpace->isNumericalTransferFn(&fn)) {
+ ALOGW("Incompatible color space, no numerical transfer function!");
+ } else {
+ float data[16];
+ xyzMatrix.asColMajorf(data);
+
+ ColorSpace::TransferParameters p =
+ {fn.fG, fn.fA, fn.fB, fn.fC, fn.fD, fn.fE, fn.fF};
+ ColorSpace src("Unnamed", mat4f((const float*) &data[0]).upperLeft(), p);
+ mConnector.reset(new ColorSpaceConnector(src, ColorSpace::sRGB()));
+
+ // A non-sRGB color space might have a transfer function close enough to sRGB
+ // that we can save shader instructions by using an sRGB sampler
+ // This is only possible if we have hardware support for sRGB textures
+ if (needSRGB && internalFormat == GL_RGBA
+ && mCaches.extensions().hasSRGB() && !bitmap.isHardware()) {
+ internalFormat = GL_SRGB8_ALPHA8;
+ }
+ }
+ }
+ }
+ }
GLenum target = bitmap.isHardware() ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
- needsAlloc |= updateSize(bitmap.width(), bitmap.height(), internalFormat, format, target);
+ needsAlloc |= updateLayout(bitmap.width(), bitmap.height(), internalFormat, format, target);
blend = !bitmap.isOpaque();
mCaches.textureState().bindTexture(mTarget, mId);
// TODO: Handle sRGB gray bitmaps
- bool hasLinearBlending = mCaches.extensions().hasLinearBlending();
- if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasLinearBlending, sRGB.get()))) {
+ if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasLinearBlending))) {
SkBitmap skBitmap;
bitmap.getSkBitmap(&skBitmap);
+ sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
SkBitmap rgbaBitmap = uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(),
rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(),
@@ -333,9 +365,28 @@ void Texture::wrap(GLuint id, uint32_t width, uint32_t height,
mFormat = format;
mInternalFormat = internalFormat;
mTarget = target;
+ mConnector.reset();
// We're wrapping an existing texture, so don't double count this memory
notifySizeChanged(0);
}
+TransferFunctionType Texture::getTransferFunctionType() const {
+ if (mConnector.get() != nullptr && mInternalFormat != GL_SRGB8_ALPHA8) {
+ const ColorSpace::TransferParameters& p = mConnector->getSource().getTransferParameters();
+ if (MathUtils::isZero(p.e) && MathUtils::isZero(p.f)) {
+ if (MathUtils::areEqual(p.a, 1.0f) && MathUtils::isZero(p.b)
+ && MathUtils::isZero(p.c) && MathUtils::isZero(p.d)) {
+ if (MathUtils::areEqual(p.g, 1.0f)) {
+ return TransferFunctionType::None;
+ }
+ return TransferFunctionType::Gamma;
+ }
+ return TransferFunctionType::Limited;
+ }
+ return TransferFunctionType::Full;
+ }
+ return TransferFunctionType::None;
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index e7fbf20cd898..052c01890317 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -19,6 +19,13 @@
#include "GpuMemoryTracker.h"
#include "hwui/Bitmap.h"
+#include "utils/Color.h"
+
+#include <memory>
+
+#include <math/mat3.h>
+
+#include <ui/ColorSpace.h>
#include <GLES2/gl2.h>
#include <EGL/egl.h>
@@ -42,8 +49,7 @@ class Texture : public GpuMemoryTracker {
public:
static SkBitmap uploadToN32(const SkBitmap& bitmap,
bool hasLinearBlending, sk_sp<SkColorSpace> sRGB);
- static bool hasUnsupportedColorType(const SkImageInfo& info,
- bool hasLinearBlending, SkColorSpace* sRGB);
+ static bool hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending);
static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType);
@@ -130,9 +136,26 @@ public:
}
/**
+ * Returns nullptr if this texture does not require color space conversion
+ * to sRGB, or a valid pointer to a ColorSpaceConnector if a conversion
+ * is required.
+ */
+ constexpr const ColorSpaceConnector* getColorSpaceConnector() const {
+ return mConnector.get();
+ }
+
+ constexpr bool hasColorSpaceConversion() const {
+ return mConnector.get() != nullptr;
+ }
+
+ TransferFunctionType getTransferFunctionType() const;
+
+ /**
* Returns true if this texture uses a linear encoding format.
*/
- bool isLinear() const;
+ constexpr bool isLinear() const {
+ return mInternalFormat == GL_RGBA16F;
+ }
/**
* Generation of the backing bitmap,
@@ -171,8 +194,8 @@ private:
// and external texture wrapper
friend class GlLayer;
- // Returns true if the size changed, false if it was the same
- bool updateSize(uint32_t width, uint32_t height, GLint internalFormat,
+ // Returns true if the texture layout (size, format, etc.) changed, false if it was the same
+ bool updateLayout(uint32_t width, uint32_t height, GLint internalFormat,
GLint format, GLenum target);
void uploadHardwareBitmapToTexture(GraphicBuffer* buffer);
void resetCachedParams();
@@ -196,6 +219,8 @@ private:
GLenum mMagFilter = GL_LINEAR;
Caches& mCaches;
+
+ std::unique_ptr<ColorSpaceConnector> mConnector;
}; // struct Texture
class AutoTexture {
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 8823a9212958..f6b2912a6254 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -491,6 +491,36 @@ Bitmap& Tree::getBitmapUpdateIfDirty() {
return *mCache.bitmap;
}
+void Tree::updateCache(sk_sp<SkSurface> surface) {
+ if (surface.get()) {
+ mCache.surface = surface;
+ }
+ if (surface.get() || mCache.dirty) {
+ SkSurface* vdSurface = mCache.surface.get();
+ SkCanvas* canvas = vdSurface->getCanvas();
+ float scaleX = vdSurface->width() / mProperties.getViewportWidth();
+ float scaleY = vdSurface->height() / mProperties.getViewportHeight();
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->clear(SK_ColorTRANSPARENT);
+ canvas->scale(scaleX, scaleY);
+ mRootNode->draw(canvas, false);
+ mCache.dirty = false;
+ canvas->flush();
+ }
+}
+
+void Tree::draw(SkCanvas* canvas) {
+ /*
+ * TODO address the following...
+ *
+ * 1) figure out how to set path's as volatile during animation
+ * 2) if mRoot->getPaint() != null either promote to layer (during
+ * animation) or cache in SkSurface (for static content)
+ */
+ canvas->drawImageRect(mCache.surface->makeImageSnapshot().get(),
+ mutateProperties()->getBounds(), getPaint());
+}
+
void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {
SkBitmap outCache;
bitmap.getSkBitmap(&outCache);
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 729a4dd4ba76..22cfe29d2aa5 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -31,6 +31,7 @@
#include <SkPathMeasure.h>
#include <SkRect.h>
#include <SkShader.h>
+#include <SkSurface.h>
#include <cutils/compiler.h>
#include <stddef.h>
@@ -677,15 +678,37 @@ public:
// This should only be called from animations on RT
TreeProperties* mutateProperties() { return &mProperties; }
+ // called from RT only
+ const TreeProperties& properties() const { return mProperties; }
+
// This should always be called from RT.
void markDirty() { mCache.dirty = true; }
bool isDirty() const { return mCache.dirty; }
bool getPropertyChangeWillBeConsumed() const { return mWillBeConsumed; }
void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; }
+ // Returns true if VD cache surface is big enough. This should always be called from RT and it
+ // works with Skia pipelines only.
+ bool canReuseSurface() {
+ SkSurface* surface = mCache.surface.get();
+ return surface && surface->width() >= mProperties.getScaledWidth()
+ && surface->height() >= mProperties.getScaledHeight();
+ }
+
+ // Draws VD cache into a canvas. This should always be called from RT and it works with Skia
+ // pipelines only.
+ void draw(SkCanvas* canvas);
+
+ // Draws VD into a GPU backed surface. If canReuseSurface returns false, then "surface" must
+ // contain a new surface. This should always be called from RT and it works with Skia pipelines
+ // only.
+ void updateCache(sk_sp<SkSurface> surface);
+
private:
struct Cache {
- sk_sp<Bitmap> bitmap;
+ sk_sp<Bitmap> bitmap; //used by HWUI pipeline and software
+ //TODO: use surface instead of bitmap when drawing in software canvas
+ sk_sp<SkSurface> surface; //used only by Skia pipelines
bool dirty = true;
};
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 72a9f4e34a2e..eed5b242c1d2 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -19,6 +19,7 @@
#include "renderthread/EglManager.h"
#include "renderthread/RenderThread.h"
#include "renderthread/RenderProxy.h"
+#include "utils/Color.h"
#include <sys/mman.h>
@@ -223,8 +224,7 @@ sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThr
return nullptr;
}
- sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
- bool needSRGB = skBitmap.info().colorSpace() == sRGB.get();
+ bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
bool hasLinearBlending = caches.extensions().hasLinearBlending();
GLint format, type, internalFormat;
uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
@@ -245,7 +245,8 @@ sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThr
SkBitmap bitmap;
if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
- hasLinearBlending, sRGB.get()))) {
+ hasLinearBlending))) {
+ sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
} else {
bitmap = skBitmap;
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 8826cfcc3100..7f06421b02a0 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -27,7 +27,5 @@ LOCAL_SHARED_LIBRARIES += \
libft2 \
libminikin \
libandroidfw \
- libRScpp
-
-LOCAL_STATIC_LIBRARIES += \
+ libRScpp \
libplatformprotos
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 496f7babd3cc..3ddc09fbeca1 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -19,6 +19,7 @@
#include "renderthread/CanvasContext.h"
#include "VectorDrawable.h"
#include "DumpOpsCanvas.h"
+#include "SkiaPipeline.h"
#include <SkImagePriv.h>
@@ -92,6 +93,8 @@ bool SkiaDisplayList::prepareListAndChildren(TreeObserver& observer, TreeInfo& i
// If any vector drawable in the display list needs update, damage the node.
if (vectorDrawable->isDirty()) {
isDirty = true;
+ static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline())
+ ->getVectorDrawables()->push_back(vectorDrawable);
}
vectorDrawable->setPropertyChangeWillBeConsumed(true);
}
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 6ee5922f9cd6..66375d13826c 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -60,7 +60,7 @@ public:
* Use the linear allocator to create any SkDrawables needed by the display
* list. This could be dangerous as these objects are ref-counted, so we
* need to monitor that they don't extend beyond the lifetime of the class
- * that creates them.
+ * that creates them. Allocator dtor invokes all SkDrawable dtors.
*/
template<class T, typename... Params>
SkDrawable* allocateDrawable(Params&&... params) {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 10c1865ac50c..75f1adc7755c 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -25,6 +25,7 @@
#include <SkPictureRecorder.h>
#include <SkPixelSerializer.h>
#include <SkStream.h>
+#include "VectorDrawable.h"
#include <unistd.h>
@@ -40,7 +41,9 @@ uint8_t SkiaPipeline::mSpotShadowAlpha = 0;
Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};
-SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) { }
+SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) {
+ mVectorDrawables.reserve(30);
+}
TaskManager* SkiaPipeline::getTaskManager() {
return &mTaskManager;
@@ -74,6 +77,7 @@ void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry
const BakedOpRenderer::LightInfo& lightInfo) {
updateLighting(lightGeometry, lightInfo);
ATRACE_NAME("draw layers");
+ renderVectorDrawableCache();
renderLayersImpl(*layerUpdateQueue, opaque);
layerUpdateQueue->clear();
}
@@ -176,10 +180,35 @@ public:
}
};
+void SkiaPipeline::renderVectorDrawableCache() {
+ //render VectorDrawables into offscreen buffers
+ for (auto vd : mVectorDrawables) {
+ sk_sp<SkSurface> surface;
+ if (!vd->canReuseSurface()) {
+#ifndef ANDROID_ENABLE_LINEAR_BLENDING
+ sk_sp<SkColorSpace> colorSpace = nullptr;
+#else
+ sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
+#endif
+ int scaledWidth = SkScalarCeilToInt(vd->properties().getScaledWidth());
+ int scaledHeight = SkScalarCeilToInt(vd->properties().getScaledHeight());
+ SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight,
+ kPremul_SkAlphaType, colorSpace);
+ SkASSERT(mRenderThread.getGrContext() != nullptr);
+ surface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+ info);
+ }
+ vd->updateCache(surface);
+ }
+ mVectorDrawables.clear();
+}
+
void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
sk_sp<SkSurface> surface) {
+ renderVectorDrawableCache();
+
// draw all layers up front
renderLayersImpl(layers, opaque);
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index c58fedf834ff..6f5e719fc2c2 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -49,6 +49,8 @@ public:
const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
sk_sp<SkSurface> surface);
+ std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; }
+
static void destroyLayer(RenderNode* node);
static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
@@ -119,8 +121,18 @@ private:
const std::vector< sp<RenderNode> >& nodes, const Rect &contentDrawBounds,
sk_sp<SkSurface>);
+ /**
+ * Render mVectorDrawables into offscreen buffers.
+ */
+ void renderVectorDrawableCache();
+
TaskManager mTaskManager;
std::vector<sk_sp<SkImage>> mPinnedImages;
+
+ /**
+ * populated by prepareTree with dirty VDs
+ */
+ std::vector<VectorDrawableRoot*> mVectorDrawables;
static float mLightRadius;
static uint8_t mAmbientShadowAlpha;
static uint8_t mSpotShadowAlpha;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 559d268b71f7..b3173f2e1974 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -62,6 +62,7 @@ void SkiaRecordingCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* lef
uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
+ // Destructor of drawables created with allocateDrawable, will be invoked by ~LinearAllocator.
drawDrawable(mDisplayList->allocateDrawable<AnimatedRoundRect>(left, top, right, bottom,
rx, ry, paint));
}
@@ -92,13 +93,14 @@ void SkiaRecordingCanvas::insertReorderBarrier(bool enableReorder) {
void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
if (layerUpdater != nullptr && layerUpdater->backingLayer() != nullptr) {
uirenderer::Layer* layer = layerUpdater->backingLayer();
+ // Create a ref-counted drawable, which is kept alive by sk_sp in SkLiteDL.
sk_sp<SkDrawable> drawable(new LayerDrawable(layer));
drawDrawable(drawable.get());
}
}
void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
- // record the child node
+ // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
auto& renderNodeDrawable = mDisplayList->mChildNodes.back();
drawDrawable(&renderNodeDrawable);
@@ -113,6 +115,7 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) {
+ // Drawable dtor will be invoked when mChildFunctors deque is cleared.
mDisplayList->mChildFunctors.emplace_back(functor, listener, asSkCanvas());
drawDrawable(&mDisplayList->mChildFunctors.back());
}
@@ -126,22 +129,7 @@ class VectorDrawable : public SkDrawable {
return SkRect::MakeLargest();
}
virtual void onDraw(SkCanvas* canvas) override {
- Bitmap& hwuiBitmap = mRoot->getBitmapUpdateIfDirty();
- SkBitmap bitmap;
- hwuiBitmap.getSkBitmap(&bitmap);
- SkPaint* paint = mRoot->getPaint();
- canvas->drawBitmapRect(bitmap, mRoot->mutateProperties()->getBounds(), paint);
- /*
- * TODO we can draw this directly but need to address the following...
- *
- * 1) Add drawDirect(SkCanvas*) to VectorDrawableRoot
- * 2) fix VectorDrawable.cpp's Path::draw to not make a temporary path
- * so that we don't break caching
- * 3) figure out how to set path's as volatile during animation
- * 4) if mRoot->getPaint() != null either promote to layer (during
- * animation) or cache in SkSurface (for static content)
- *
- */
+ mRoot->draw(canvas);
}
private:
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 8bce990129de..c8833d2a7489 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -22,8 +22,11 @@
#include "renderthread/CanvasContext.h"
#include "renderthread/EglManager.h"
#include "utils/GLUtils.h"
+
#include <algorithm>
+#include <ui/ColorSpace.h>
+
namespace android {
namespace uirenderer {
@@ -359,6 +362,40 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) {
fill.skiaShaderData.bitmapData.bitmapTexture : nullptr;
const AutoTexture autoCleanup(texture);
+ // If we have a shader and a base texture, the base texture is assumed to be an alpha mask
+ // which means the color space conversion applies to the shader's bitmap
+ Texture* colorSpaceTexture = texture != nullptr ? texture : fill.texture.texture;
+ if (colorSpaceTexture != nullptr) {
+ if (colorSpaceTexture->hasColorSpaceConversion()) {
+ const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector();
+ glUniformMatrix3fv(fill.program->getUniform("colorSpaceMatrix"), 1,
+ GL_FALSE, connector->getTransform().asArray());
+ }
+
+ TransferFunctionType transferFunction = colorSpaceTexture->getTransferFunctionType();
+ if (transferFunction != TransferFunctionType::None) {
+ const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector();
+ const ColorSpace& source = connector->getSource();
+
+ switch (transferFunction) {
+ case TransferFunctionType::None:
+ break;
+ case TransferFunctionType::Full:
+ glUniform1fv(fill.program->getUniform("transferFunction"), 7,
+ reinterpret_cast<const float*>(&source.getTransferParameters().g));
+ break;
+ case TransferFunctionType::Limited:
+ glUniform1fv(fill.program->getUniform("transferFunction"), 5,
+ reinterpret_cast<const float*>(&source.getTransferParameters().g));
+ break;
+ case TransferFunctionType::Gamma:
+ glUniform1f(fill.program->getUniform("transferFunctionGamma"),
+ source.getTransferParameters().g);
+ break;
+ }
+ }
+ }
+
// ------------------------------------
// ---------- GL state setup ----------
// ------------------------------------
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 738c09141a7a..33eda96a2d77 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -194,6 +194,8 @@ public:
void waitOnFences();
+ IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }
+
private:
CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index e32fd63e1125..1450ec98dabf 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -98,6 +98,7 @@ void TaskQueue::queue(RenderTask* task) {
}
void TaskQueue::queueAtFront(RenderTask* task) {
+ LOG_ALWAYS_FATAL_IF(task->mNext || mHead == task, "Task is already in the queue!");
if (mTail) {
task->mNext = mHead;
mHead = task;
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index 7ae58a68a76c..e15f5d95fc51 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -17,6 +17,7 @@
#include "tests/common/TestUtils.h"
#include <gtest/gtest.h>
+#include <SkBlurDrawLooper.h>
#include <SkColorMatrixFilter.h>
#include <SkColorSpace.h>
#include <SkImagePriv.h>
@@ -95,3 +96,16 @@ TEST(SkiaBehavior, srgbColorSpaceIsSingleton) {
sk_sp<SkColorSpace> sRGB2 = SkColorSpace::MakeSRGB();
ASSERT_EQ(sRGB1.get(), sRGB2.get());
}
+
+TEST(SkiaBehavior, blurDrawLooper) {
+ sk_sp<SkDrawLooper> looper = SkBlurDrawLooper::Make(SK_ColorRED, 5.0f, 3.0f, 4.0f);
+
+ SkDrawLooper::BlurShadowRec blur;
+ bool success = looper->asABlurShadow(&blur);
+ ASSERT_TRUE(success);
+
+ ASSERT_EQ(SK_ColorRED, blur.fColor);
+ ASSERT_EQ(5.0f, blur.fSigma);
+ ASSERT_EQ(3.0f, blur.fOffset.fX);
+ ASSERT_EQ(4.0f, blur.fOffset.fY);
+}
diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp
new file mode 100644
index 000000000000..7d234b06b8ca
--- /dev/null
+++ b/libs/hwui/utils/Color.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#include "Color.h"
+
+#include <cmath>
+
+namespace android {
+namespace uirenderer {
+
+static inline bool almostEqual(float a, float b) {
+ return std::abs(a - b) < 1e-2f;
+}
+
+bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace) {
+ if (colorSpace == nullptr) return true;
+ if (colorSpace->isSRGB()) return true;
+
+ SkColorSpaceTransferFn transferFunction;
+ if (colorSpace->isNumericalTransferFn(&transferFunction)) {
+ // sRGB transfer function params:
+ const float sRGBParamA = 1 / 1.055f;
+ const float sRGBParamB = 0.055f / 1.055f;
+ const float sRGBParamC = 1 / 12.92f;
+ const float sRGBParamD = 0.04045f;
+ const float sRGBParamE = 0.0f;
+ const float sRGBParamF = 0.0f;
+ const float sRGBParamG = 2.4f;
+
+ // This comparison will catch Display P3
+ return
+ almostEqual(sRGBParamA, transferFunction.fA)
+ && almostEqual(sRGBParamB, transferFunction.fB)
+ && almostEqual(sRGBParamC, transferFunction.fC)
+ && almostEqual(sRGBParamD, transferFunction.fD)
+ && almostEqual(sRGBParamE, transferFunction.fE)
+ && almostEqual(sRGBParamF, transferFunction.fF)
+ && almostEqual(sRGBParamG, transferFunction.fG);
+ }
+
+ return false;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h
index 4a27ca2f327a..9c096601c826 100644
--- a/libs/hwui/utils/Color.h
+++ b/libs/hwui/utils/Color.h
@@ -19,6 +19,7 @@
#include <math.h>
#include <SkColor.h>
+#include <SkColorSpace.h>
namespace android {
namespace uirenderer {
@@ -82,6 +83,13 @@ namespace uirenderer {
};
static constexpr int BrightColorsCount = sizeof(BrightColors) / sizeof(Color::Color);
+ enum class TransferFunctionType : int8_t {
+ None = 0,
+ Full,
+ Limited,
+ Gamma
+ };
+
// Opto-electronic conversion function for the sRGB color space
// Takes a linear sRGB value and converts it to a gamma-encoded sRGB value
static constexpr float OECF_sRGB(float linear) {
@@ -118,6 +126,11 @@ namespace uirenderer {
return srgb;
#endif
}
+
+ // Returns whether the specified color space's transfer function can be
+ // approximated with the native sRGB transfer function. This method
+ // returns true for sRGB, gamma 2.2 and Display P3 for instance
+ bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace);
} /* namespace uirenderer */
} /* namespace android */
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index ce58a9c4b91e..77a82ec8cacd 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -912,6 +912,8 @@ public final class AudioAttributes implements Parcelable {
return USAGE_UNKNOWN;
}
}
+
+ // TODO remove, replaced by non-static API getVolumeControlStream()
/**
* Returns the stream type matching the given attributes for volume control.
* Use this method to derive the stream type needed to configure the volume
@@ -925,6 +927,7 @@ public final class AudioAttributes implements Parcelable {
* the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
* match. Note that <code>USE_DEFAULT_STREAM_TYPE</code> is not a valid value
* for {@link AudioManager#setStreamVolume(int, int, int)}.
+ * @deprecated use {@link #getVolumeControlStream()}
*/
public static int getVolumeControlStream(@NonNull AudioAttributes aa) {
if (aa == null) {
@@ -934,6 +937,24 @@ public final class AudioAttributes implements Parcelable {
}
/**
+ * 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
+ * {@link android.app.Activity#setVolumeControlStream(int)} for playback conducted with these
+ * attributes.
+ * <BR>Do not use this method to set the stream type on an audio player object
+ * (e.g. {@link AudioTrack}, {@link MediaPlayer}) as this is deprecated,
+ * use {@code AudioAttributes} instead.
+ * @return a valid stream type for {@code Activity} or stream volume control that matches
+ * the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
+ * match. Note that {@code USE_DEFAULT_STREAM_TYPE} is not a valid value
+ * for {@link AudioManager#setStreamVolume(int, int, int)}.
+ */
+ public int getVolumeControlStream() {
+ return toVolumeStreamType(true /*fromGetVolumeControlStream*/, this);
+ }
+
+ /**
* @hide
* Only use to get which stream type should be used for volume control, NOT for audio playback
* (all audio playback APIs are supposed to take AudioAttributes as input parameters)
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index b60dbd572b93..0a1de33b845b 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -15,6 +15,7 @@
*/
package android.media;
+import android.util.IntArray;
import com.android.server.LocalServices;
/**
@@ -43,6 +44,8 @@ public abstract class AudioManagerInternal {
public abstract void updateRingerModeAffectedStreamsInternal();
+ public abstract void setAccessibilityServiceUids(IntArray uids);
+
public interface RingerModeDelegate {
/** Called when external ringer mode is evaluated, returns the new internal ringer mode */
int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index abf6b203daaf..2a0e04ebf051 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -62,6 +62,7 @@ class ImageUtils {
case ImageFormat.RAW12:
case ImageFormat.DEPTH16:
case ImageFormat.DEPTH_POINT_CLOUD:
+ case ImageFormat.RAW_DEPTH:
return 1;
case ImageFormat.PRIVATE:
return 0;
@@ -103,6 +104,10 @@ class ImageUtils {
throw new IllegalArgumentException(
"Copy of RAW_OPAQUE format has not been implemented");
}
+ if (src.getFormat() == ImageFormat.RAW_DEPTH) {
+ throw new IllegalArgumentException(
+ "Copy of RAW_DEPTH format has not been implemented");
+ }
if (!(dst.getOwner() instanceof ImageWriter)) {
throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
+ " the images from ImageWriter are writable");
@@ -206,6 +211,7 @@ class ImageUtils {
case PixelFormat.RGB_565:
case ImageFormat.YUY2:
case ImageFormat.Y16:
+ case ImageFormat.RAW_DEPTH:
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
case ImageFormat.DEPTH16:
@@ -253,6 +259,7 @@ class ImageUtils {
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW10:
case ImageFormat.RAW12:
+ case ImageFormat.RAW_DEPTH:
return new Size(image.getWidth(), image.getHeight());
case ImageFormat.PRIVATE:
return new Size(0, 0);
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 2e22132614d2..611fdd1d997b 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -18,6 +18,7 @@ package android.media;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.media.MediaCasException.*;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -28,6 +29,7 @@ import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Singleton;
@@ -84,8 +86,6 @@ import android.util.Singleton;
* sessionId of the descrambler can be retrieved by {@link MediaExtractor#getDrmInitData}
* and used to initialize a MediaDescrambler object for MediaCodec.
* <p>
- * TODO: determine exception handling schemes.
- * <p>
* <h3>Listeners</h3>
* <p>The app may register a listener to receive events from the CA system using
* method {@link #setEventListener}. The exact format of the event is scheme-specific
@@ -382,28 +382,22 @@ public final class MediaCas {
mEventHandler = new EventHandler(looper);
}
- /*
- * TODO: handle ServiceSpecificException from the IMediaCas
- * All Drm-specific failures will be thrown by mICas as
- * ServiceSpecificException exception with Drm error code.
- * These need to be re-thrown as crypto exceptions.
- */
-
/**
* Send the private data for the CA system.
*
* @param data byte array of the private data.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- /*
- * TODO: need to re-throw DRM-specific exceptions
- */
- public void setPrivateData(@NonNull byte[] data) {
+ public void setPrivateData(@NonNull byte[] data) throws MediaCasException {
validateInternalStates();
try {
mICas.setPrivateData(data);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -416,14 +410,17 @@ public final class MediaCas {
*
* @return session id of the newly opened session.
*
- * @throws IllegalStateException if the MediaCas instance is not valid,
- * or IllegalArgumentException if a session for the program already exists.
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public byte[] openSession(int programNumber) {
+ public byte[] openSession(int programNumber) throws MediaCasException {
validateInternalStates();
try {
return mICas.openSession(programNumber);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -438,14 +435,18 @@ public final class MediaCas {
*
* @return session id of the newly opened session.
*
- * @throws IllegalStateException if the MediaCas instance is not valid,
- * or IllegalArgumentException if a session for the stream already exists.
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public byte[] openSession(int programNumber, int elementaryPID) {
+ public byte[] openSession(int programNumber, int elementaryPID)
+ throws MediaCasException {
validateInternalStates();
try {
return mICas.openSessionForStream(programNumber, elementaryPID);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -457,14 +458,16 @@ public final class MediaCas {
*
* @param sessionId the session to be closed.
*
- * @throws IllegalStateException if the MediaCas instance is not valid,
- * or IllegalArgumentException if the session is not valid.
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
public void closeSession(@NonNull byte[] sessionId) {
validateInternalStates();
try {
mICas.closeSession(sessionId);
+ } catch (ServiceSpecificException e) {
+ MediaCasStateException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -476,17 +479,18 @@ public final class MediaCas {
* @param sessionId the session for which the private data is intended.
* @param data byte array of the private data.
*
- * @throws IllegalStateException if the MediaCas instance is not valid,
- * or IllegalArgumentException if the session is not valid.
- */
- /*
- * TODO: need to re-throw DRM-specific exceptions
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public void setSessionPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data) {
+ public void setSessionPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data)
+ throws MediaCasException {
validateInternalStates();
try {
mICas.setSessionPrivateData(sessionId, data);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -500,19 +504,19 @@ public final class MediaCas {
* @param offset position within data where the ECM data begins.
* @param length length of the data (starting from offset).
*
- * @throws IllegalStateException if the MediaCas instance is not valid,
- * or IllegalArgumentException if the session is not valid.
- */
- /*
- * TODO: need to re-throw DRM-specific exceptions
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public void processEcm(
- @NonNull byte[] sessionId, @NonNull byte[] data, int offset, int length) {
+ public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data,
+ int offset, int length) throws MediaCasException {
validateInternalStates();
try {
mCasData.set(data, offset, length);
mICas.processEcm(sessionId, mCasData);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -526,13 +530,12 @@ public final class MediaCas {
* @param sessionId the session for which the ECM is intended.
* @param data byte array of the ECM data.
*
- * @throws IllegalStateException if the MediaCas instance is not valid,
- * or IllegalArgumentException if the session is not valid.
- */
- /*
- * TODO: need to re-throw DRM-specific exceptions
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data) {
+ public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data)
+ throws MediaCasException {
processEcm(sessionId, data, 0, data.length);
}
@@ -544,16 +547,18 @@ public final class MediaCas {
* @param length length of the data (starting from offset).
*
* @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- /*
- * TODO: need to re-throw DRM-specific exceptions
- */
- public void processEmm(@NonNull byte[] data, int offset, int length) {
+ public void processEmm(@NonNull byte[] data, int offset, int length)
+ throws MediaCasException {
validateInternalStates();
try {
mCasData.set(data, offset, length);
mICas.processEmm(mCasData);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -567,11 +572,10 @@ public final class MediaCas {
* @param data byte array of the EMM data.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- /*
- * TODO: need to re-throw DRM-specific exceptions
- */
- public void processEmm(@NonNull byte[] data) {
+ public void processEmm(@NonNull byte[] data) throws MediaCasException {
processEmm(data, 0, data.length);
}
@@ -584,12 +588,17 @@ public final class MediaCas {
* @param data a byte array containing scheme-specific data for the event.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public void sendEvent(int event, int arg, @Nullable byte[] data) {
+ public void sendEvent(int event, int arg, @Nullable byte[] data)
+ throws MediaCasException {
validateInternalStates();
try {
mICas.sendEvent(event, arg, data);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -603,12 +612,16 @@ public final class MediaCas {
* specific.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- public void provision(@NonNull String provisionString) {
+ public void provision(@NonNull String provisionString) throws MediaCasException {
validateInternalStates();
try {
mICas.provision(provisionString);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -621,15 +634,17 @@ public final class MediaCas {
* @param refreshData private data associated with the refreshment.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
- /*
- * TODO: define enums for refreshType
- */
- public void refreshEntitlements(int refreshType, @Nullable byte[] refreshData) {
+ public void refreshEntitlements(int refreshType, @Nullable byte[] refreshData)
+ throws MediaCasException {
validateInternalStates();
try {
mICas.refreshEntitlements(refreshType, refreshData);
+ } catch (ServiceSpecificException e) {
+ MediaCasException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
diff --git a/media/java/android/media/MediaCasException.java b/media/java/android/media/MediaCasException.java
index 1d5d3cdb2134..485f6eebf88e 100644
--- a/media/java/android/media/MediaCasException.java
+++ b/media/java/android/media/MediaCasException.java
@@ -16,11 +16,104 @@
package android.media;
+import android.os.ServiceSpecificException;
+
/**
* Base class for MediaCas exceptions
*/
public class MediaCasException extends Exception {
+
+ /** @hide */
+ public static final int DRM_ERROR_BASE = -2000;
+ /** @hide */
+ public static final int ERROR_DRM_UNKNOWN = DRM_ERROR_BASE;
+ /** @hide */
+ public static final int ERROR_DRM_NO_LICENSE = DRM_ERROR_BASE - 1;
+ /** @hide */
+ public static final int ERROR_DRM_LICENSE_EXPIRED = DRM_ERROR_BASE - 2;
+ /** @hide */
+ public static final int ERROR_DRM_SESSION_NOT_OPENED = DRM_ERROR_BASE - 3;
+ /** @hide */
+ public static final int ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED = DRM_ERROR_BASE - 4;
+ /** @hide */
+ public static final int ERROR_DRM_DECRYPT = DRM_ERROR_BASE - 5;
+ /** @hide */
+ public static final int ERROR_DRM_CANNOT_HANDLE = DRM_ERROR_BASE - 6;
+ /** @hide */
+ public static final int ERROR_DRM_TAMPER_DETECTED = DRM_ERROR_BASE - 7;
+ /** @hide */
+ public static final int ERROR_DRM_NOT_PROVISIONED = DRM_ERROR_BASE - 8;
+ /** @hide */
+ public static final int ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9;
+ /** @hide */
+ public static final int ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10;
+ /** @hide */
+ public static final int ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11;
+ /** @hide */
+ public static final int ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11;
+ /** @hide */
+ public static final int ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500;
+ /** @hide */
+ public static final int ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999;
+
+ /** @hide */
public MediaCasException(String detailMessage) {
super(detailMessage);
}
+
+ static void throwExceptions(ServiceSpecificException e) throws MediaCasException {
+ if (e.errorCode == ERROR_DRM_NOT_PROVISIONED) {
+ throw new NotProvisionedException(e.getMessage());
+ } else if (e.errorCode == ERROR_DRM_RESOURCE_BUSY) {
+ throw new ResourceBusyException(e.getMessage());
+ } else if (e.errorCode == ERROR_DRM_DEVICE_REVOKED) {
+ throw new DeniedByServerException(e.getMessage());
+ } else {
+ MediaCasStateException.throwExceptions(e);
+ }
+ }
+
+ /**
+ * Exception thrown when an attempt is made to construct a MediaCas object
+ * using a CA_system_id that is not supported by the device
+ */
+ public static final class UnsupportedCasException extends MediaCasException {
+ /** @hide */
+ public UnsupportedCasException(String detailMessage) {
+ super(detailMessage);
+ }
+ }
+
+ /**
+ * Exception thrown when an operation on a MediaCas object is attempted
+ * before it's provisioned successfully.
+ */
+ public static final class NotProvisionedException extends MediaCasException {
+ /** @hide */
+ public NotProvisionedException(String detailMessage) {
+ super(detailMessage);
+ }
+ }
+
+ /**
+ * Exception thrown when the provisioning server or key server denies a
+ * license for a device.
+ */
+ public static final class DeniedByServerException extends MediaCasException {
+ /** @hide */
+ public DeniedByServerException(String detailMessage) {
+ super(detailMessage);
+ }
+ }
+
+ /**
+ * Exception thrown when an operation on a MediaCas object is attempted
+ * and hardware resources are not available, due to being in use.
+ */
+ public static final class ResourceBusyException extends MediaCasException {
+ /** @hide */
+ public ResourceBusyException(String detailMessage) {
+ super(detailMessage);
+ }
+ }
}
diff --git a/media/java/android/media/MediaCasStateException.java b/media/java/android/media/MediaCasStateException.java
new file mode 100644
index 000000000000..cf05c2975272
--- /dev/null
+++ b/media/java/android/media/MediaCasStateException.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.ServiceSpecificException;
+
+import static android.media.MediaCasException.*;
+
+/**
+ * Base class for MediaCas runtime exceptions
+ */
+public class MediaCasStateException extends IllegalStateException {
+ private final int mErrorCode;
+ private final String mDiagnosticInfo;
+
+ /** @hide */
+ public MediaCasStateException(int err, @Nullable String msg, @Nullable String diagnosticInfo) {
+ super(msg);
+ mErrorCode = err;
+ mDiagnosticInfo = diagnosticInfo;
+ }
+
+ static void throwExceptions(ServiceSpecificException e) {
+ String diagnosticInfo = "";
+ switch (e.errorCode) {
+ case ERROR_DRM_UNKNOWN:
+ diagnosticInfo = "General CAS error";
+ break;
+ case ERROR_DRM_NO_LICENSE:
+ diagnosticInfo = "No license";
+ break;
+ case ERROR_DRM_LICENSE_EXPIRED:
+ diagnosticInfo = "License expired";
+ break;
+ case ERROR_DRM_SESSION_NOT_OPENED:
+ diagnosticInfo = "Session not opened";
+ break;
+ case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
+ diagnosticInfo = "Not initialized";
+ break;
+ case ERROR_DRM_DECRYPT:
+ diagnosticInfo = "Decrypt error";
+ break;
+ case ERROR_DRM_CANNOT_HANDLE:
+ diagnosticInfo = "Unsupported scheme or data format";
+ break;
+ case ERROR_DRM_TAMPER_DETECTED:
+ diagnosticInfo = "Tamper detected";
+ break;
+ default:
+ diagnosticInfo = "Unknown CAS state exception";
+ break;
+ }
+ throw new MediaCasStateException(e.errorCode, e.getMessage(),
+ String.format("%s (err=%d)", diagnosticInfo, e.errorCode));
+ }
+
+ /**
+ * Retrieve the associated error code
+ *
+ * @hide
+ */
+ public int getErrorCode() {
+ return mErrorCode;
+ }
+
+ /**
+ * Retrieve a developer-readable diagnostic information string
+ * associated with the exception. Do not show this to end-users,
+ * since this string will not be localized or generally comprehensible
+ * to end-users.
+ */
+ @NonNull
+ public String getDiagnosticInfo() {
+ return mDiagnosticInfo;
+ }
+}
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 13a22b49ff87..7ee0a7d6359c 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -1878,9 +1878,7 @@ final public class MediaCodec {
* @param flags Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
* component as an encoder.
* @param descrambler Specify a descrambler object to facilitate secure
- * descrambling of the media data. descrambler must not be
- * null if this method is used. For non-secure codecs, use
- * {@link #configure} and with null crypto parameter.
+ * descrambling of the media data, or null for non-secure codecs.
* @throws IllegalArgumentException if the surface has been released (or is invalid),
* or the format is unacceptable (e.g. missing a mandatory key),
* or the flags are not set properly
@@ -1891,8 +1889,9 @@ final public class MediaCodec {
*/
public void configure(
@Nullable MediaFormat format, @Nullable Surface surface,
- @ConfigureFlag int flags, @NonNull MediaDescrambler descrambler) {
- configure(format, surface, null, descrambler.getBinder(), flags);
+ @ConfigureFlag int flags, @Nullable MediaDescrambler descrambler) {
+ configure(format, surface, null,
+ descrambler != null ? descrambler.getBinder() : null, flags);
}
private void configure(
@@ -2441,6 +2440,8 @@ final public class MediaCodec {
}
};
+ private final Pattern zeroPattern = new Pattern(0, 0);
+
/**
* The pattern applicable to the protected data in each subsample.
*/
@@ -2463,7 +2464,7 @@ final public class MediaCodec {
key = newKey;
iv = newIV;
mode = newMode;
- pattern = new Pattern(0, 0);
+ pattern = zeroPattern;
}
/**
diff --git a/media/java/android/media/MediaDescrambler.java b/media/java/android/media/MediaDescrambler.java
index f5eede859eb1..2dd109721ca8 100644
--- a/media/java/android/media/MediaDescrambler.java
+++ b/media/java/android/media/MediaDescrambler.java
@@ -17,10 +17,12 @@
package android.media;
import android.annotation.NonNull;
+import android.media.MediaCasException.UnsupportedCasException;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import java.nio.ByteBuffer;
@@ -54,13 +56,13 @@ public final class MediaDescrambler {
/**
* Class for parceling descrambling parameters over IDescrambler binder.
*/
+ // This class currently is not used by Java binder. descramble() goes through
+ // jni to use shared memory. However, the parcelable is still required for AIDL.
static class DescrambleInfo implements Parcelable {
private DescrambleInfo() {
- // TODO: implement
}
private DescrambleInfo(Parcel in) {
- // TODO: disable
}
@Override
@@ -70,7 +72,6 @@ public final class MediaDescrambler {
@Override
public void writeToParcel(Parcel dest, int flags) {
- // TODO: implement
}
public static final Parcelable.Creator<DescrambleInfo> CREATOR
@@ -112,13 +113,6 @@ public final class MediaDescrambler {
return mIDescrambler.asBinder();
}
- /*
- * TODO: handle ServiceSpecificException from the mIDescrambler
- * All Drm-specific failures will be thrown by mIDescrambler as
- * ServiceSpecificException exception with Drm error code.
- * These need to be re-thrown as crypto exceptions.
- */
-
/**
* Query if the scrambling scheme requires the use of a secure decoder
* to decode data of the given mime type.
@@ -150,14 +144,16 @@ public final class MediaDescrambler {
* @param sessionId the MediaCas sessionId to associate with this
* MediaDescrambler instance.
*
- * @throws IllegalStateException if the descrambler instance is not valid,
- * or IllegalArgumentException if the sessionId is not valid.
+ * @throws IllegalStateException if the descrambler instance is not valid.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
public final void setMediaCasSession(@NonNull byte[] sessionId) {
validateInternalStates();
try {
mIDescrambler.setMediaCasSession(sessionId);
+ } catch (ServiceSpecificException e) {
+ MediaCasStateException.throwExceptions(e);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -179,9 +175,7 @@ public final class MediaDescrambler {
* values indicating errors.
*
* @throws IllegalStateException if the descrambler instance is not valid.
- */
- /*
- * TODO: throw DRM-specific exception if decrambling is failing.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
*/
public final int descramble(
@NonNull ByteBuffer srcBuf, int srcPos, ByteBuffer dstBuf, int dstPos,
@@ -208,12 +202,17 @@ public final class MediaDescrambler {
"Invalid CryptoInfo: key array is invalid!");
}
- return native_descramble(
- cryptoInfo.key[0],
- cryptoInfo.numSubSamples,
- cryptoInfo.numBytesOfClearData,
- cryptoInfo.numBytesOfEncryptedData,
- srcBuf, srcPos, dstBuf, dstPos);
+ try {
+ return native_descramble(
+ cryptoInfo.key[0],
+ cryptoInfo.numSubSamples,
+ cryptoInfo.numBytesOfClearData,
+ cryptoInfo.numBytesOfEncryptedData,
+ srcBuf, srcPos, dstBuf, dstPos);
+ } catch (ServiceSpecificException e) {
+ MediaCasStateException.throwExceptions(e);
+ }
+ return -1;
}
public final void release() {
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index bee3f52c9b90..f10f4427d6f0 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -77,13 +77,19 @@ public final class MediaSession {
/**
* Set this flag on the session to indicate that it can handle media button
* events.
+ * @deprecated This flag is no longer used. All media sessions are expected to handle media
+ * button events now.
*/
+ @Deprecated
public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1 << 0;
/**
* Set this flag on the session to indicate that it handles transport
* control commands through its {@link Callback}.
+ * @deprecated This flag is no longer used. All media sessions are expected to handle transport
+ * controls now.
*/
+ @Deprecated
public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
/**
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 6808b57c2642..7bf69c06ab5e 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1321,9 +1321,7 @@ public final class TvContract {
*
* <p>Type: INTEGER (boolean)
* @see Channels#COLUMN_TRANSIENT
- * @hide
*/
- @SystemApi
public static final String COLUMN_TRANSIENT = "transient";
/**
@@ -2164,10 +2162,9 @@ public final class TvContract {
* specified, this value is set to 0 (not transient) by default.
*
* <p>Type: INTEGER (boolean)
- * @see Programs#COLUMN_TRANSIENT
- * @hide
+ * @see PreviewPrograms#COLUMN_TRANSIENT
+ * @see WatchNextPrograms#COLUMN_TRANSIENT
*/
- @SystemApi
public static final String COLUMN_TRANSIENT = "transient";
/**
diff --git a/media/java/android/media/tv/TvInputHardwareInfo.java b/media/java/android/media/tv/TvInputHardwareInfo.java
index 957c5820838e..762f0c07e121 100644
--- a/media/java/android/media/tv/TvInputHardwareInfo.java
+++ b/media/java/android/media/tv/TvInputHardwareInfo.java
@@ -20,6 +20,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.hardware.tv.input.V1_0.Constants;
import android.media.AudioManager;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,16 +38,16 @@ public final class TvInputHardwareInfo implements Parcelable {
static final String TAG = "TvInputHardwareInfo";
// Match hardware/libhardware/include/hardware/tv_input.h
- public static final int TV_INPUT_TYPE_OTHER_HARDWARE = 1;
- public static final int TV_INPUT_TYPE_TUNER = 2;
- public static final int TV_INPUT_TYPE_COMPOSITE = 3;
- public static final int TV_INPUT_TYPE_SVIDEO = 4;
- public static final int TV_INPUT_TYPE_SCART = 5;
- public static final int TV_INPUT_TYPE_COMPONENT = 6;
- public static final int TV_INPUT_TYPE_VGA = 7;
- public static final int TV_INPUT_TYPE_DVI = 8;
- public static final int TV_INPUT_TYPE_HDMI = 9;
- public static final int TV_INPUT_TYPE_DISPLAY_PORT = 10;
+ public static final int TV_INPUT_TYPE_OTHER_HARDWARE = Constants.TV_INPUT_TYPE_OTHER;
+ public static final int TV_INPUT_TYPE_TUNER = Constants.TV_INPUT_TYPE_TUNER;
+ public static final int TV_INPUT_TYPE_COMPOSITE = Constants.TV_INPUT_TYPE_COMPOSITE;
+ public static final int TV_INPUT_TYPE_SVIDEO = Constants.TV_INPUT_TYPE_SVIDEO;
+ public static final int TV_INPUT_TYPE_SCART = Constants.TV_INPUT_TYPE_SCART;
+ public static final int TV_INPUT_TYPE_COMPONENT = Constants.TV_INPUT_TYPE_COMPONENT;
+ public static final int TV_INPUT_TYPE_VGA = Constants.TV_INPUT_TYPE_VGA;
+ public static final int TV_INPUT_TYPE_DVI = Constants.TV_INPUT_TYPE_DVI;
+ public static final int TV_INPUT_TYPE_HDMI = Constants.TV_INPUT_TYPE_HDMI;
+ public static final int TV_INPUT_TYPE_DISPLAY_PORT = Constants.TV_INPUT_TYPE_DISPLAY_PORT;
/** @hide */
@Retention(SOURCE)
@@ -58,17 +59,20 @@ public final class TvInputHardwareInfo implements Parcelable {
/**
* The hardware is unsure about the connection status or does not support cable detection.
*/
- public static final int CABLE_CONNECTION_STATUS_UNKNOWN = 0;
+ public static final int CABLE_CONNECTION_STATUS_UNKNOWN =
+ Constants.CABLE_CONNECTION_STATUS_UNKNOWN;
/**
* Cable is connected to the hardware.
*/
- public static final int CABLE_CONNECTION_STATUS_CONNECTED = 1;
+ public static final int CABLE_CONNECTION_STATUS_CONNECTED =
+ Constants.CABLE_CONNECTION_STATUS_CONNECTED;
/**
* Cable is disconnected to the hardware.
*/
- public static final int CABLE_CONNECTION_STATUS_DISCONNECTED = 2;
+ public static final int CABLE_CONNECTION_STATUS_DISCONNECTED =
+ Constants.CABLE_CONNECTION_STATUS_DISCONNECTED;
public static final Parcelable.Creator<TvInputHardwareInfo> CREATOR =
new Parcelable.Creator<TvInputHardwareInfo>() {
diff --git a/media/jni/android_media_MediaDescrambler.cpp b/media/jni/android_media_MediaDescrambler.cpp
index 75856648f498..f031dbb273c6 100644
--- a/media/jni/android_media_MediaDescrambler.cpp
+++ b/media/jni/android_media_MediaDescrambler.cpp
@@ -129,7 +129,7 @@ void JDescrambler::ensureBufferCapacity(size_t neededSize) {
mMem = mDealer->allocate(neededSize);
}
-ssize_t JDescrambler::descramble(
+Status JDescrambler::descramble(
jbyte key,
size_t numSubSamples,
ssize_t totalLength,
@@ -137,7 +137,8 @@ ssize_t JDescrambler::descramble(
const void *srcPtr,
jint srcOffset,
void *dstPtr,
- jint dstOffset) {
+ jint dstOffset,
+ ssize_t *result) {
// TODO: IDescrambler::descramble() is re-entrant, however because we
// only have 1 shared mem buffer, we can only do 1 descramble at a time.
// Concurrency might be improved by allowing on-demand allocation of up
@@ -159,16 +160,16 @@ ssize_t JDescrambler::descramble(
info.dstPtr = NULL;
info.dstOffset = 0;
- int32_t result;
- binder::Status status = mDescrambler->descramble(info, &result);
+ int32_t descrambleResult;
+ Status status = mDescrambler->descramble(info, &descrambleResult);
- if (!status.isOk() || result > totalLength) {
- return -1;
- }
- if (result > 0) {
- memcpy((void*)((uint8_t*)dstPtr + dstOffset), mMem->pointer(), result);
+ if (status.isOk()) {
+ *result = (descrambleResult <= totalLength) ? descrambleResult : -1;
+ if (*result > 0) {
+ memcpy((void*)((uint8_t*)dstPtr + dstOffset), mMem->pointer(), *result);
+ }
}
- return result;
+ return status;
}
} // namespace android
@@ -251,11 +252,45 @@ static ssize_t getSubSampleInfo(JNIEnv *env, jint numSubSamples,
numBytesOfClearData = NULL;
}
+ if (totalSize < 0) {
+ delete[] subSamples;
+ return -1;
+ }
+
*outSubSamples = subSamples;
return totalSize;
}
+static jthrowable createServiceSpecificException(
+ JNIEnv *env, int serviceSpecificError, const char *msg) {
+ if (env->ExceptionCheck()) {
+ ALOGW("Discarding pending exception");
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+
+ ScopedLocalRef<jclass> clazz(
+ env, env->FindClass("android/os/ServiceSpecificException"));
+ CHECK(clazz.get() != NULL);
+
+ const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V");
+ CHECK(ctor != NULL);
+
+ ScopedLocalRef<jstring> msgObj(
+ env, env->NewStringUTF(msg != NULL ?
+ msg : String8::format("Error %#x", serviceSpecificError)));
+
+ return (jthrowable)env->NewObject(
+ clazz.get(), ctor, serviceSpecificError, msgObj.get());
+}
+
+static void throwServiceSpecificException(
+ JNIEnv *env, int serviceSpecificError, const char *msg) {
+ jthrowable exception = createServiceSpecificException(env, serviceSpecificError, msg);
+ env->Throw(exception);
+}
+
static jint android_media_MediaDescrambler_native_descramble(
JNIEnv *env, jobject thiz, jbyte key, jint numSubSamples,
jintArray numBytesOfClearDataObj, jintArray numBytesOfEncryptedDataObj,
@@ -290,11 +325,11 @@ static jint android_media_MediaDescrambler_native_descramble(
env, dstBuf, dstOffset, totalLength, &dstPtr, &dstArray);
}
}
-
+ Status status;
if (err == OK) {
- result = descrambler->descramble(
+ status = descrambler->descramble(
key, numSubSamples, totalLength, subSamples,
- srcPtr, srcOffset, dstPtr, dstOffset);
+ srcPtr, srcOffset, dstPtr, dstOffset, &result);
}
delete[] subSamples;
@@ -304,6 +339,51 @@ static jint android_media_MediaDescrambler_native_descramble(
if (dstArray != NULL) {
env->ReleaseByteArrayElements(dstArray, (jbyte *)dstPtr, 0);
}
+
+ if (!status.isOk()) {
+ switch (status.exceptionCode()) {
+ case Status::EX_SECURITY:
+ jniThrowException(env, "java/lang/SecurityException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_BAD_PARCELABLE:
+ jniThrowException(env, "java/lang/BadParcelableException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_ILLEGAL_ARGUMENT:
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_NULL_POINTER:
+ jniThrowException(env, "java/lang/NullPointerException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_ILLEGAL_STATE:
+ jniThrowException(env, "java/lang/IllegalStateException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_NETWORK_MAIN_THREAD:
+ jniThrowException(env, "java/lang/NetworkOnMainThreadException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_UNSUPPORTED_OPERATION:
+ jniThrowException(env, "java/lang/UnsupportedOperationException",
+ status.exceptionMessage());
+ break;
+ case Status::EX_SERVICE_SPECIFIC:
+ throwServiceSpecificException(env, status.serviceSpecificErrorCode(),
+ status.exceptionMessage());
+ break;
+ default:
+ {
+ String8 msg;
+ msg.appendFormat("Unknown exception code: %d, msg: %s",
+ status.exceptionCode(), status.exceptionMessage().string());
+ jniThrowException(env, "java/lang/RuntimeException", msg.string());
+ break;
+ }
+ }
+ }
return result;
}
diff --git a/media/jni/android_media_MediaDescrambler.h b/media/jni/android_media_MediaDescrambler.h
index e944a90dba7a..aeef05e7968d 100644
--- a/media/jni/android_media_MediaDescrambler.h
+++ b/media/jni/android_media_MediaDescrambler.h
@@ -19,6 +19,7 @@
#include "jni.h"
+#include <binder/Status.h>
#include <media/cas/DescramblerAPI.h>
#include <media/stagefright/foundation/ABase.h>
#include <utils/Mutex.h>
@@ -31,11 +32,12 @@ namespace media {
class IDescrambler;
};
using namespace media;
+using binder::Status;
struct JDescrambler : public RefBase {
JDescrambler(JNIEnv *env, jobject descramberBinderObj);
- ssize_t descramble(
+ Status descramble(
jbyte key,
size_t numSubSamples,
ssize_t totalLength,
@@ -43,7 +45,8 @@ struct JDescrambler : public RefBase {
const void *srcPtr,
jint srcOffset,
void *dstPtr,
- jint dstOffset);
+ jint dstOffset,
+ ssize_t *result);
protected:
virtual ~JDescrambler();
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index 8df194c11800..e450283312c3 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -27,7 +27,9 @@
<uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
- <application android:label="@string/app_name" >
+ <application
+ android:label="@string/app_name"
+ android:directBootAware="true">
<receiver android:name="com.android.carrierdefaultapp.CarrierDefaultBroadcastReceiver">
<intent-filter>
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index e49463f04ec6..227d8048292a 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -58,6 +58,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.Preconditions;
@@ -109,6 +110,11 @@ public class DeviceDiscoveryService extends Service {
private final ScanCallback mBLEScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
+ if (DEBUG) {
+ Log.i(LOG_TAG,
+ "BLE.onScanResult(callbackType = " + callbackType + ", result = " + result
+ + ")");
+ }
final DeviceFilterPair<ScanResult> deviceFilterPair
= DeviceFilterPair.findMatch(result, mBLEFilters);
if (deviceFilterPair == null) return;
@@ -125,6 +131,10 @@ public class DeviceDiscoveryService extends Service {
private BroadcastReceiver mBluetoothDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ if (DEBUG) {
+ Log.i(LOG_TAG,
+ "BL.onReceive(context = " + context + ", intent = " + intent + ")");
+ }
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
final DeviceFilterPair<BluetoothDevice> deviceFilterPair
= DeviceFilterPair.findMatch(device, mBluetoothFilters);
@@ -180,15 +190,23 @@ public class DeviceDiscoveryService extends Service {
}
private void startDiscovery(AssociationRequest request) {
- mRequest = request;
+ if (!request.equals(mRequest)) {
+ mRequest = request;
+
+ mFilters = request.getDeviceFilters();
+ mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class);
+ mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class);
+ mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLEDeviceFilter.class);
+ mBLEScanFilters = CollectionUtils.map(mBLEFilters, BluetoothLEDeviceFilter::getScanFilter);
+
+ reset();
+ } else if (DEBUG) Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request);
- mFilters = request.getDeviceFilters();
- mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class);
- mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class);
- mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLEDeviceFilter.class);
- mBLEScanFilters = CollectionUtils.map(mBLEFilters, BluetoothLEDeviceFilter::getScanFilter);
- reset();
+
+ if (!ArrayUtils.isEmpty(mDevicesFound)) {
+ onReadyToShowUI();
+ }
if (shouldScan(mBluetoothFilters)) {
final IntentFilter intentFilter = new IntentFilter();
@@ -215,6 +233,7 @@ public class DeviceDiscoveryService extends Service {
}
private void reset() {
+ if (DEBUG) Log.i(LOG_TAG, "reset()");
mDevicesFound.clear();
mSelectedDevice = null;
mDevicesAdapter.notifyDataSetChanged();
@@ -228,10 +247,18 @@ public class DeviceDiscoveryService extends Service {
private void stopScan() {
if (DEBUG) Log.i(LOG_TAG, "stopScan() called");
- mBluetoothAdapter.cancelDiscovery();
- mBLEScanner.stopScan(mBLEScanCallback);
- unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver);
- unregisterReceiver(mWifiDeviceFoundBroadcastReceiver);
+
+ if (shouldScan(mBluetoothFilters)) {
+ mBluetoothAdapter.cancelDiscovery();
+ unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver);
+ }
+ if (shouldScan(mBLEFilters)) {
+ mBLEScanner.stopScan(mBLEScanCallback);
+ }
+ if (shouldScan(mWifiFilters)) {
+ unregisterReceiver(mWifiDeviceFoundBroadcastReceiver);
+ }
+
stopSelf();
}
@@ -355,8 +382,15 @@ public class DeviceDiscoveryService extends Service {
public static <T extends Parcelable> DeviceFilterPair<T> findMatch(
T dev, @Nullable List<? extends DeviceFilter<T>> filters) {
if (isEmpty(filters)) return new DeviceFilterPair<>(dev, null);
- final DeviceFilter<T> matchingFilter = CollectionUtils.find(filters, (f) -> f.matches(dev));
- return matchingFilter != null ? new DeviceFilterPair<>(dev, matchingFilter) : null;
+ final DeviceFilter<T> matchingFilter
+ = CollectionUtils.find(filters, f -> f.matches(dev));
+
+ DeviceFilterPair<T> result = matchingFilter != null
+ ? new DeviceFilterPair<>(dev, matchingFilter)
+ : null;
+ if (DEBUG) Log.i(LOG_TAG, "findMatch(dev = " + dev + ", filters = " + filters +
+ ") -> " + result);
+ return result;
}
public String getDisplayName() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 187e35ac842c..f11a9cde9520 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -113,12 +113,14 @@ public final class RemotePrintDocument {
}
// Notify we are done.
mState = STATE_UPDATED;
+ mDocumentInfo.updated = true;
notifyUpdateCompleted();
}
}
} else {
// We always notify after a write.
mState = STATE_UPDATED;
+ mDocumentInfo.updated = true;
notifyUpdateCompleted();
}
runPendingCommand();
@@ -229,6 +231,7 @@ public final class RemotePrintDocument {
mDocumentInfo, oldAttributes, attributes, preview, mCommandResultCallback);
scheduleCommand(command);
+ mDocumentInfo.updated = false;
mState = STATE_UPDATING;
// If no layout in progress and we don't have all pages - schedule a write.
} else if ((!(mCurrentCommand instanceof LayoutCommand)
@@ -249,6 +252,7 @@ public final class RemotePrintDocument {
mDocumentInfo.fileProvider, mCommandResultCallback);
scheduleCommand(command);
+ mDocumentInfo.updated = false;
mState = STATE_UPDATING;
} else {
willUpdate = false;
@@ -396,7 +400,7 @@ public final class RemotePrintDocument {
private void notifyUpdateFailed(CharSequence error) {
if (DEBUG) {
- Log.i(LOG_TAG, "[CALLING] onUpdateCompleted()");
+ Log.i(LOG_TAG, "[CALLING] notifyUpdateFailed()");
}
mUpdateCallbacks.onUpdateFailed(error);
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index f6df9953bf0f..4cce166db645 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -491,8 +491,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
setState(STATE_UPDATE_FAILED);
- updateOptionsUi();
-
mPrintedDocument.kill(message);
}
@@ -502,7 +500,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
&& canUpdateDocument() && updateDocument(true)) {
ensurePreviewUiShown();
setState(STATE_CONFIGURING);
- updateOptionsUi();
}
}
@@ -579,7 +576,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
updatePrintPreviewController(document.changed);
setState(STATE_CONFIGURING);
- updateOptionsUi();
} break;
}
}
@@ -600,8 +596,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
setState(STATE_UPDATE_FAILED);
-
- updateOptionsUi();
}
@Override
@@ -734,7 +728,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
updateOptionsUi();
} else {
setState(STATE_CREATE_FILE_FAILED);
- updateOptionsUi();
// Calling finish here does not invoke lifecycle callbacks but we
// update the print job in onPause if finishing, hence post a message.
mDestinationSpinner.post(new Runnable() {
@@ -958,12 +951,14 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
Log.i(LOG_TAG, "[state]" + state);
}
mState = state;
+ updateOptionsUi();
}
} else {
if (DEBUG) {
Log.i(LOG_TAG, "[state]" + state);
}
mState = state;
+ updateOptionsUi();
}
}
@@ -1230,6 +1225,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
final boolean willUpdate = mPrintedDocument.update(mPrintJob.getAttributes(),
pages, preview);
+ updateOptionsUi();
if (willUpdate && !mPrintedDocument.hasLaidOutPages()) {
// When the update is done we update the print preview.
@@ -1254,7 +1250,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
private void cancelPrint() {
setState(STATE_PRINT_CANCELED);
- updateOptionsUi();
mPrintedDocument.cancel(true);
doFinish();
}
@@ -1274,7 +1269,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
private void confirmPrint() {
setState(STATE_PRINT_CONFIRMED);
- updateOptionsUi();
addCurrentPrinterToHistory();
setUserPrinted();
@@ -1629,6 +1623,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
// Always update the summary.
updateSummary();
+ mDestinationSpinner.setEnabled(!isFinalState(mState));
+
if (mState == STATE_PRINT_CONFIRMED
|| mState == STATE_PRINT_COMPLETED
|| mState == STATE_PRINT_CANCELED
@@ -1636,9 +1632,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
|| mState == STATE_CREATE_FILE_FAILED
|| mState == STATE_PRINTER_UNAVAILABLE
|| mState == STATE_UPDATE_SLOW) {
- if (mState != STATE_PRINTER_UNAVAILABLE) {
- mDestinationSpinner.setEnabled(false);
- }
disableOptionsUi(isFinalState(mState));
return;
}
@@ -1927,7 +1920,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mPrintButton.setImageResource(R.drawable.ic_menu_savetopdf);
mPrintButton.setContentDescription(getString(R.string.savetopdf_button));
}
- if (!mPrintedDocument.getDocumentInfo().laidout
+ if (!mPrintedDocument.getDocumentInfo().updated
||(mRangeOptionsSpinner.getSelectedItemPosition() == 1
&& (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
|| (mRangeOptionsSpinner.getSelectedItemPosition() == 0
@@ -2048,7 +2041,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
updateDocument(false);
}
ensurePreviewUiShown();
- updateOptionsUi();
}
}
@@ -2058,7 +2050,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mPrintedDocument.cancel(false);
ensureErrorUiShown(getString(R.string.print_error_printer_unavailable),
PrintErrorFragment.ACTION_NONE);
- updateOptionsUi();
}
}
@@ -3038,7 +3029,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
if (mState == STATE_UPDATE_SLOW) {
setState(STATE_UPDATE_SLOW);
ensureProgressUiShown();
- updateOptionsUi();
return;
} else if (mPosted) {
@@ -3080,7 +3070,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
mPreviousState = mState;
setState(STATE_UPDATE_SLOW);
ensureProgressUiShown();
- updateOptionsUi();
}
}
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index d8df0d7413f3..6d6d2653ae3b 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Gebruik HDCP-kontrolering net vir DRM-inhoud"</item>
<item msgid="45075631231212732">"Gebruik altyd HDCP-kontrolering"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (verstek)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Gebruik stelselkeuse (verstek)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Geoptimeer vir oudiogehalte (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Gebalanseerde oudio- en verbindinggehalte (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Geoptimeer vir verbindinggehalte (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Geoptimeer vir oudiogehalte"</item>
- <item msgid="4327143584633311908">"Gebalanseerde oudio- en verbindinggehalte"</item>
- <item msgid="4681409244565426925">"Geoptimeer vir verbindinggehalte"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Af"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index c4be395c7d05..671849f8beea 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Sal nie outomaties koppel nie"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Geen internettoegang nie"</string>
<string name="saved_network" msgid="4352716707126620811">"Gestoor deur <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Outomaties deur %1$s gekoppel"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Gekoppel via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Baie snel"</item>
<item msgid="9085102246155045744">"Vinnigste"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Kies profiel"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Persoonlik"</string>
<string name="category_work" msgid="8699184680584175622">"Werk"</string>
<string name="development_settings_title" msgid="215179176067683667">"Ontwikkelaaropsies"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Inligtingruiling"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Draadlose skermsertifisering"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiveer Wi-Fi-woordryke aanmelding"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiewe Wi‑Fi-na-mobiel-oorhandiging"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Laat altyd Wi-Fi-swerfskanderings toe"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiveer absolute volume"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-weergawe"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Kies Bluetooth AVRCP-weergawe"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-oudiokodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Kies Bluetooth-oudiokodek"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth-oudiovoorbeeldkoers"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Stroming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wanneer dit geaktiveer is, sal Wi-Fi die dataverbinding aggressiewer na mobiel oordra wanneer die Wi-Fi-sein swak is"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Laat toe of verbied Wi-Fi-swerfskanderings op grond van die hoeveelheid dataverkeer wat op die koppelvlak teenwoordig is"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Loggerbuffer se groottes"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Kies loggergroottes per logbuffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ongeveer <xliff:g id="TIME">%1$s</xliff:g> oor"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> oor"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai met AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai met USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai met draadloos"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Beheer deur administrateur"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Geaktiveer deur administrateur"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Gedeaktiveer deur administrateur"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Instellingstuisblad"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index f613311e3df6..73dadec2d1aa 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"ለDRM ይዘት ብቻ HDCP ምልከታን ተጠቀም"</item>
<item msgid="45075631231212732">"ሁልጊዜ የHDCP ምልከታ ተጠቀም"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ነባሪ)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"ሞኖ"</item>
<item msgid="8883739882299884241">"ስቲሪዮ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ለኦዲዮ ጥራት ተብቷል (990 ኪቢ/ሴ / 909 ኪቢ/ሴ)"</item>
- <item msgid="2921767058740704969">"ለኦዲዮ ጥራት አትባ (660 ኪቢ/ሴ / 606 ኪቢ/ሴ)"</item>
- <item msgid="8860982705384396512">"ለግንኙነት ጥራት ተብቷል (330 ኪቢ/ሴ / 303 ኪቢ/ሴ)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ለኦዲዮ ጥራት ተብቷል"</item>
- <item msgid="4327143584633311908">"የተመጣጠነ የኦዲዮ እና ግንኙነት ጥራት"</item>
- <item msgid="4681409244565426925">"ለግንኙነት ጥራት ተብቷል"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ጠፍቷል"</item>
<item msgid="1593289376502312923">"64 ኪባ"</item>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 0a94e7c3b29a..fa7ea7d721c7 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"በራስ-ሰር አይገናኝም"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ምንም የበይነመረብ መዳረሻ ያለም"</string>
<string name="saved_network" msgid="4352716707126620811">"የተቀመጠው በ<xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"በ%1$s በኩል በራስ-ሰር ተገናኝቷል"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"በ%1$s በኩል መገናኘት"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"በጣም ቀልጣፋ"</item>
<item msgid="9085102246155045744">"እጅግ በጣም ቀልጣፋ"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"መገለጫ ይምረጡ"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"የግል"</string>
<string name="category_work" msgid="8699184680584175622">"ስራ"</string>
<string name="development_settings_title" msgid="215179176067683667">"የገንቢዎች አማራጮች"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"አውታረ መረብ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"የWi‑Fi ተጨማሪ ቃላት ምዝግብ ማስታወሻ መያዝ"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"አስገዳጅ ከWi‑Fi ወደ ሞባይል ማቀበል"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ሁልጊዜ የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ፍጹማዊ ድምፅን አሰናክል"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"የብሉቱዝ AVRCP ስሪት"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"የብሉቱዝ AVRCP ስሪት ይምረጡ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"የብሉቱዝ ኦዲዮ ኮዴክ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"የብሉቱዝ ኦዲዮ ኮዴክ ይምረጡ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"የብሉቱዝ ኦዲዮ ናሙና ፍጥነት"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ዥረት፦ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ሲነቃ የWi‑Fi ምልክት ዝቅተኛ ሲሆን Wi‑Fi የውሂብ ግንኙነት ለሞባይል ማስረከብ ላይ ይበልጥ አስገዳጅ ይሆናል"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"በበይነገጹ ላይ ባለው የውሂብ ትራፊክ መጠን ላይ ተመስርተው የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ/ይከልክሉ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"የምዝግብ ማስታወሻ ያዥ መጠኖች"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"በአንድ ምዝግብ ማስታወሻ ቋጥ የሚኖረው የምዝግብ ማስታወሻ ያዥ መጠኖች ይምረጡ"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> ገደማ ቀርቷል"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> አካባቢ ይቀራል"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - በAC ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - በዩኤስቢ በኩል ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - በገመድ አልባ ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ያልታወቀ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል እየሞላ አይደለም"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"በአስተዳዳሪ የነቃ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"በአስተዳዳሪ የተሰናከለ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"የቅንብሮች መነሻ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index 9e29fe6eef6b..8fceb11fd5fb 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"‏استخدام التحقق من HDCP لمحتوى DRM فقط"</item>
<item msgid="45075631231212732">"‏استخدام التحقق من HDCP دومًا"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"‏AVRCP 1.4 (الافتراضي)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"استخدام اختيار النظام (افتراضي)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"أحادي"</item>
<item msgid="8883739882299884241">"استريو"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"تحسين جودة الصوت (٩٩٠ كيلوبت في الثانية / ٩٠٩ كيلوبت في الثانية)"</item>
- <item msgid="2921767058740704969">"جودة متوازنة للصوت والاتصال (660 كيلوبت في الثانية/606 كيلوبت في الثانية)"</item>
- <item msgid="8860982705384396512">"تحسين جودة الاتصال (٣٣٠ كيلوبت في الثانية / ٣٠٣ كيلوبت في الثانية)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"تحسين جودة الصوت"</item>
- <item msgid="4327143584633311908">"جودة متوازنة للصوت والاتصال"</item>
- <item msgid="4681409244565426925">"تحسين جودة الاتصال"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"إيقاف"</item>
<item msgid="1593289376502312923">"٦٤ كيلوبايت"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 875f526a143f..82a6a8a19708 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -26,15 +26,14 @@
<string name="wifi_disabled_generic" msgid="4259794910584943386">"معطلة"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"‏أخفقت تهيئة عنوان IP"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"الجهاز غير متصل بسبب انخفاض جودة الشبكة"</string>
- <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"‏أخفق اتصال WiFi"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"‏تعذّر اتصال WiFi"</string>
<string name="wifi_disabled_password_failure" msgid="8659805351763133575">"حدثت مشكلة في المصادقة"</string>
<string name="wifi_not_in_range" msgid="1136191511238508967">"ليست في النطاق"</string>
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"لن يتم الاتصال تلقائيًا"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"لا يتوفر اتصال بالإنترنت"</string>
<string name="saved_network" msgid="4352716707126620811">"تم الحفظ بواسطة <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"‏تم الاتصال تلقائيًا عبر %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"‏تم الاتصال عبر %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"‏متوفرة عبر %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"خاطف جدًا"</item>
<item msgid="9085102246155045744">"الأسرع"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"اختيار ملف شخصي"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"شخصي"</string>
<string name="category_work" msgid="8699184680584175622">"العمل"</string>
<string name="development_settings_title" msgid="215179176067683667">"خيارات مطور البرامج"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"الشبكات"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"‏تمكين تسجيل Wi‑Fi Verbose"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏تسليم Wi-Fi حاد إلى جوّال"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏السماح دائمًا بعمليات فحص Wi-Fi للتجوال"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"تعطيل مستوى الصوت المطلق"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏إصدار Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"‏اختيار إصدار Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ترميز صوت بلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"اختيار برنامج الترميز لصوت البلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"معدّل عيّنة صوت بلوتوث"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"البث: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"‏عند تمكينه، سيكون Wi-Fi أكثر حدة في تسليم اتصال البيانات إلى الجوّال، وذلك عندما تكون إشارة WiFi منخفضة"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"‏السماح/عدم السماح بعمليات فحص Wi-Fi للتجوال بناءً على حجم حركة البيانات في الواجهة"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"أحجام ذاكرة التخزين المؤقت للتسجيل"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"حدد أحجامًا أكبر لكل ذاكرة تخزين مؤقت للتسجيل"</string>
@@ -286,7 +281,7 @@
<string name="local_backup_password_summary_change" msgid="5376206246809190364">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
<string name="local_backup_password_toast_success" msgid="582016086228434290">"تم تعيين كلمة مرور احتياطية جديدة"</string>
<string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"كلمة المرور الجديدة وتأكيدها لا يتطابقان"</string>
- <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"أخفق تعيين كلمة مرور احتياطية"</string>
+ <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"تعذّر تعيين كلمة مرور احتياطية"</string>
<string-array name="color_mode_names">
<item msgid="2425514299220523812">"نابض بالحياة (افتراضي)"</item>
<item msgid="8446070607501413455">"طبيعي"</item>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> تقريبًا"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"يتبقى <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن عبر التيار المتردد"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن عبر USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن اللاسلكي"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"شحن"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"إعدادات يتحكم فيها المشرف"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"تم التمكين بواسطة المشرف"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"تم التعطيل بواسطة المشرف"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"الشاشة الرئيسية للإعدادات"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"٠‏٪"</item>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index 2313161df8d1..a4e0e173b2a2 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Yalnız DRM məzmun oxumaq üçün HDCP istifadə edin"</item>
<item msgid="45075631231212732">"Həmişə HDCP yoxlama istifadə edin"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Defolt)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Sistem Seçimini istifadə edin (Defolt)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Audio Keyfiyyəti üçün optimallaşdırıldı (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanslı Audio və Bağlantı Keyfiyyəti (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Bağlantı Keyfiyyəti üçün optimallaşdırıldı (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Audio Keyfiyyəti üçün optimallaşdırıldı"</item>
- <item msgid="4327143584633311908">"Balanslı Audio və Bağlantı Keyfiyyəti"</item>
- <item msgid="4681409244565426925">"Bağlantı Keyfiyyəti üçün optimallaşdırıldı"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Deaktiv"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 138ff6feff5c..01f524a0e8c4 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Avtomatik qoşulmayacaq"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"İnternet girişi yoxdur"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> tərəfindən saxlandı"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s üzərindən avtomatik qoşuldu"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s vasitəsilə qoşuludur"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Çox tez"</item>
<item msgid="9085102246155045744">"Ən sürətli"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profil Seçin"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Şəxsi"</string>
<string name="category_work" msgid="8699184680584175622">"İş"</string>
<string name="development_settings_title" msgid="215179176067683667">"Developer seçimləri"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Şəbəkələşmə"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz displey sertifikatlaşması"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Möbül ötürücüyə aqressiv Wi‑Fi"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi axtarışlarına həmişə icazə verin"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mütləq səs həcmi deaktiv edin"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Versiya"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP Versiyasını seçin"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth Audio Kodeki Seçin"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Nümunə Göstəricisi"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Canlı yayım: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Aktiv edildikdə, Wi-Fi siqnalı zəif olan zaman, data bağlantısını mobilə ötürərəkən Wi-Fi daha aqressiv olacaq"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Wi‑Fi Axtarışlarına data trafikinə əsasən İcazə verin/Qadağan edin"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger bufer ölçüləri"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Hər jurnal buferinı Logger ölçüsü seçin"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tam enerji yığana kimi"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC\'də tam enerji yığana kimi"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ilə tam enerji yığana kimi"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> Wi-Fi\'dan tam enerji yığana kimi"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Naməlum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Admin tərəfindən nəzarət olunur"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Administrator tərəfindən aktiv edildi"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Administrator tərəfindən deaktiv edildi"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ayarların əsas səhifəsi"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 7d098761c545..56709ec1b218 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Koristi HDCP proveru samo za DRM sadržaj"</item>
<item msgid="45075631231212732">"Uvek koristi HDCP proveru"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (podrazumevano)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Koristi izbor sistema (podrazumevano)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizovano za kvalitet zvuka (990 kb/s/909 kb/s)"</item>
- <item msgid="2921767058740704969">"Ujednačen kvalitet zvuka i veze (660 kb/s/606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optimizovano za kvalitet veze (330 kb/s/303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizovano za kvalitet zvuka"</item>
- <item msgid="4327143584633311908">"Ujednačen kvalitet zvuka i veze"</item>
- <item msgid="4681409244565426925">"Optimizovano za kvalitet veze"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Isključeno"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 24b2a13854c3..ba3d592f8703 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automatsko povezivanje nije uspelo"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
<string name="saved_network" msgid="4352716707126620811">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano preko %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Veoma ubrzano"</item>
<item msgid="9085102246155045744">"Najbrže"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Izaberite profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Lično"</string>
<string name="category_work" msgid="8699184680584175622">"Posao"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opcije za programera"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivan prelaz sa Wi‑Fi mreže na mobilnu"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvek dozvoli skeniranje Wi‑Fi-ja u romingu"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući glavno podešavanje jačine zvuka"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija Bluetooth AVRCP-a"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Izaberite verziju Bluetooth AVRCP-a"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Izaberite Bluetooth audio kodek"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kad se omogući, Wi‑Fi će biti agresivniji pri prebacivanju mreže za prenos podataka na mobilnu ako je Wi‑Fi signal slab"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/zabrani skeniranje Wi-Fi-ja u romingu na osnovu prisutnog protoka podataka na interfejsu"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine po baferu evidencije"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Preostalo vreme: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ostalo je oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"Preostalo je <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja preko utičnice"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja preko USB-a"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja na bežičnoj mreži"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontroliše administrator"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio je administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Početna za Podešavanja"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index 6c883e3e0c54..76e1f95da93f 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Выкарыстанне праверкі HDCP только для змесціва, абароненага DRM"</item>
<item msgid="45075631231212732">"Заўсёды выкарыстоўваць праверку HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (стандартная)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Выбар сістэмы (стандартны)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Мона"</item>
<item msgid="8883739882299884241">"Стэрэа"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Аптымізавана якасць гуку (990 кбіт/c / 909 кбіт/c)"</item>
- <item msgid="2921767058740704969">"Збалансаваная якасць аўдыя і падключэння (660кбіт/c / 606 кбіт/c)"</item>
- <item msgid="8860982705384396512">"Аптымізавана якасць падключэння (330 кбіт/c / 303 кбіт/c)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Аптымізавана якасць гуку"</item>
- <item msgid="4327143584633311908">"Збалансаваная якасць аўдыя і падключэння"</item>
- <item msgid="4681409244565426925">"Аптымізавана якасць падключэння"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Выкл."</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 36ebaa309636..7071e52a7e86 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не будзе аўтаматычна падключацца"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Няма доступу да інтэрнэту"</string>
<string name="saved_network" msgid="4352716707126620811">"Хто захаваў: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Аўтаматычна падключана праз %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Падлучана праз %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Вельмі шпарка"</item>
<item msgid="9085102246155045744">"Максімальна хутка"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Выбраць профіль"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Асабісты"</string>
<string name="category_work" msgid="8699184680584175622">"Рабочы"</string>
<string name="development_settings_title" msgid="215179176067683667">"Параметры распрацоўшчыка"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Сеткі"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сертыфікацыя бесправаднога дысплея"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Уключыць падрабязны журнал Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Інтэнсіўны пераход з Wi‑Fi на маб. сетку"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Заўсёды дазваляць роўмінгавае сканіраванне Wi‑Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Адключыць абсалютны гук"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Выбраць версію Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодэк Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Выбраць аўдыякодэк Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частата дыскрэтызацыі Bluetooth Audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Перадача плынню: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога дысплея"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Падвыс. узровень дэтал-цыі журнала Wi‑Fi у залежн. ад SSID RSSI у Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Калі гэта функцыя ўключана, Wi-Fi будзе больш інтэнсіўна імкнуцца перайсці на падключ. маб. перад. даных пры слабым сігнале Wi‑Fi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дазволіць/забараніць роўмінгавае сканіраванне Wi‑Fi ў залежнасці ад аб\'ёму трафіку даных у інтэрфейсе"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера для сродку вядзення журнала"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Выберыце памеры сродку вядзення журнала для буфераў журнала"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Засталося прыблізна <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося каля <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі ад сеткі пер. току"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі па USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай бесправадной зарадкі"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Невядома"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Кантралюецца адміністратарам"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Уключана адміністратарам"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Адключана адміністратарам"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Галоўная старонка налад"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 98d216e4dd8c..48407958ebdd 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Да се използва проверка с HDCP само за DRM съдържание"</item>
<item msgid="45075631231212732">"Винаги да се използва проверка с HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (по подразбиране)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Използване на сист. избор (стандартно)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Оптимизирано за качество на звука (990 или 909 кб/сек)"</item>
- <item msgid="2921767058740704969">"Балансирано качество на звука и връзката (660 или 606 кб/сек)"</item>
- <item msgid="8860982705384396512">"Оптимизирано за качество на връзката (330 или 303 кб/сек)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Оптимизирано за качество на звука"</item>
- <item msgid="4327143584633311908">"Балансирано качество на звука и връзката"</item>
- <item msgid="4681409244565426925">"Оптимизирано за качество на връзката"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Изключено"</item>
<item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 9e1ffbb706c9..69b84a84ec29 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Няма да се свърже автоматично"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Няма достъп до интернет"</string>
<string name="saved_network" msgid="4352716707126620811">"Запазено от <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматично е установена връзка чрез %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Установена е връзка през „%1$s“"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Свръхбърза"</item>
<item msgid="9085102246155045744">"Най-бърза"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Избиране на потр. профил"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Лични"</string>
<string name="category_work" msgid="8699184680584175622">"Служебни"</string>
<string name="development_settings_title" msgid="215179176067683667">"Опции на програмиста"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Мрежи"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Безжичен дисплей"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"„Многословно“ регистр. на Wi‑Fi: Актив."</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi към моб. мрежи: Агресивно предав."</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Сканирането за роуминг на Wi-Fi да е разрешено винаги"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Деактивиране на пълната сила на звука"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия на AVRCP за Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Избиране на версия на AVRCP за Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Аудиокодек за Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Изберете аудиокодек за Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Честота на дискретизация за звука през Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Поточно предаване: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"При активиране предаването на връзката за данни от Wi-Fi към мобилната мрежа ще е по-агресивно, когато сигналът за Wi-Fi е слаб"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Разрешаване/забраняване на сканирането за роуминг на Wi-Fi въз основа на посочения в интерфейса обем на трафика на данни"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Размери на регистрац. буфери"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Размер на един рег. буфер: Избор"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Прибл. оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – около <xliff:g id="TIME">%2$s</xliff:g> оставащо време"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане при променлив ток"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане през USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно безжично зареждане"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролира се от администратор"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Активирано от администратора"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Деактивирано от администратора"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Начален екран на Настройки"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index 7a868219ccc8..cd40a63da602 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"শুধুমাত্র DRM সামগ্রীর জন্য HDCP চেক করা ব্যবহার করুন"</item>
<item msgid="45075631231212732">"সর্বদা HDCP পরীক্ষণ ব্যবহার করুন"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ডিফল্ট)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"মোনো"</item>
<item msgid="8883739882299884241">"স্টিরিও"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"অডিও গুণমানের জন্য অপ্টিমাইজ করা হয়েছে (৯৯০kbps/৯০৯kbps)"</item>
- <item msgid="2921767058740704969">"সন্তুলিত গুণমানের অডিও এবং সংযোগ (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"সংযোগের গুণমানের জন্য অপটিমাইজ করা হয়েছে (৩৩০kbps/৩০৩kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"অডিও গুণমানের জন্য অপ্টিমাইজ করা হয়েছে"</item>
- <item msgid="4327143584633311908">"সন্তুলিত গুণমানের অডিও এবং সংযোগ"</item>
- <item msgid="4681409244565426925">"সংযোগের গুণমানের জন্য অপটিমাইজ করা হয়েছে"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"বন্ধ আছে"</item>
<item msgid="1593289376502312923">"৬৪K"</item>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 54cde462a343..443326c6fcc8 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"স্বয়ংক্রিয়ভাবে সংযোগ করবে না"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"কোনো ইন্টারনেট অ্যাক্সেস নেই"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> দ্বারা সংরক্ষিত"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"স্বয়ংক্রিয়ভাবে %1$s এর মাধ্যমে সংযুক্ত হয়েছে"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে সংযুক্ত হয়েছে"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"খুব দ্রুত"</item>
<item msgid="9085102246155045744">"দ্রুততম"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"প্রোফাইল বেছে নিন"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string>
<string name="category_work" msgid="8699184680584175622">"কর্মক্ষেত্র"</string>
<string name="development_settings_title" msgid="215179176067683667">"বিকাশকারী বিকল্পগুলি"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ওয়াই-ফাই থেকে মোবাইলে তৎপর হস্তান্তর"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা Wifi রোম স্ক্যানকে অনুমতি দিন"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"চূড়ান্ত ভলিউম অক্ষম করুন"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP সংস্করণ"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ব্লুটুথ AVRCP সংস্করণ বেছে নিন"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ব্লুটুথ অডিও কোডেক"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ব্লুটুথ অডিও কোডেক বেছে নিন"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ব্লুটুথ অডিওর নমুনা হার"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"স্ট্রিমিং: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"সক্ষম করা থাকলে, ওয়াই ফাই সিগন্যালের মান খারাপ হলে ডেটা সংযোগ মোবাইলের কাছে হস্তান্তর করার জন্য ওয়াই ফাই আরো বেশি তৎপর হবে।"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ইন্টারফেসে উপস্থিত ডেটা ট্রাফিকের পরিমাণের উপরে ভিত্তি করে ওয়াই-ফাই রোম স্ক্যানকে অনুমোদিত/অননুমোদিত করুন"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"লগ বাফার প্রতি অপেক্ষাকৃত বড় আকারগুলির নির্বাচন করুন"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"প্রায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - প্রায় <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC তে সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB এর মাধ্যমে সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - ওয়্যারলেস এর মাধ্যমে সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> সময় লাগবে"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"অজানা"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"চার্জ হচ্ছে"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"চার্জ হচ্ছে না"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"প্রশাসক সক্ষম করেছেন"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"প্রশাসক অক্ষম করেছেন"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"সেটিংস হোম"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"০%"</item>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 58b3a47d0030..4cbf09d308e8 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Koristi HDCP provjeru samo za DRM sadržaj"</item>
<item msgid="45075631231212732">"Uvijek koristi HDCP provjeru"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Zadano)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Koristi odabir sistema (Zadano)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizirano za kvalitet zvuka (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Uravnotežen kvalitet zvuka i veze (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Optimizirano za kvalitet veze (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizirano za kvalitet zvuka"</item>
- <item msgid="4327143584633311908">"Uravnotežen kvalitet zvuka i veze"</item>
- <item msgid="4681409244565426925">"Optimizirano za kvalitet veze"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Isključeno"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index ce40282174fd..79b701ebfe10 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se automatski povezati"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
<string name="saved_network" msgid="4352716707126620811">"Sačuvao <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano koristeći %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Veoma ubrzano"</item>
<item msgid="9085102246155045744">"Najbrže"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Odaberite profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Lično"</string>
<string name="category_work" msgid="8699184680584175622">"Posao"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opcije za programere"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogućiti Wi-Fi Verbose zapisivanje"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivni prijenos s Wi-Fi mreže na mob."</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopustiti Wi-Fi lutajuće skeniranje"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna mreža za prijenos podataka je uvijek aktivna"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogućite apsolutnu jačinu zvuka"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP verzija"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Odaberite Bluetooth AVRCP verziju"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Odaberite Bluetooth Audio kodek"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži opcije za certifikaciju Bežičnog prikaza"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećajte nivo Wi-Fi zapisivanja, pokazati po SSID RSSI Wi-Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kada je omogućeno, Wi-Fi veza će u slučaju slabog signala agresivnije predavati vezu za prijenos podataka na mobilnu vezu"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/Zabrani Wi-Fi lutajuće skeniranje na osnovu količine podatkovnog prometa prisutnog na sučelju"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera za zapisnik"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine za Logger prema međumemoriji evidencije"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti na adapteru"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti putem USB-a"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti bežično"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pod kontrolom administratora"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Postavke početne stranice"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 3aa72c540e7e..0d79a81a1151 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utilitza la comprovació HDCP només per a contingut DRM"</item>
<item msgid="45075631231212732">"Utilitza sempre la comprovació HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminada)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Utilitza selecció del sistema (predeterminada)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estèreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimitzat per a la qualitat de l\'àudio (990 kbps / 909 kbps)"</item>
- <item msgid="2921767058740704969">"Qualitat equilibrada de l\'àudio i la connexió (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimitzat per a la qualitat de la connexió (330 kbps / 303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimitzat per a la qualitat de l\'àudio"</item>
- <item msgid="4327143584633311908">"Qualitat equilibrada de l\'àudio i la connexió"</item>
- <item msgid="4681409244565426925">"Optimitzat per a la qualitat de la connexió"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"No"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index e2ba5dd682fe..1645c197f54d 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No es connectarà automàticament"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"No hi ha accés a Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Desat per <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connectada automàticament a través de: %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Molt veloç"</item>
<item msgid="9085102246155045744">"Màxima"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Triar un perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Feina"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opcions per a desenvolupadors"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Xarxes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificació de pantalla sense fil"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Activa el registre Wi‑Fi detallat"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferència agressiva de Wi-Fi a mòbil"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permet sempre cerca de Wi-Fi en ininerància"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactiva el volum absolut"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versió AVRCP de Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona la versió AVRCP de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Còdec d\'àudio per Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecciona el còdec d\'àudio per Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Velocitat de mostra d’àudio per Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"S\'està reproduint en temps real: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions de certificació de pantalla sense fil"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi i mostra\'l per SSID RSSI al Selector de Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quan s\'activa, la Wi-Fi és més agressiva en transferir la connexió de dades al mòbil quan el senyal de la Wi-Fi sigui dèbil"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permet/No permetis cerques de xarxes Wi-Fi en itinerància basades en la quantitat de dades presents a la interfície"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Mides memòria intermèdia Logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Mida Logger per memòria intermèdia"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Temps restant aproximat: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> aproximadament per esgotar la bateria"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>; temps restant: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega amb CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega per USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega sense fil"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconegut"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"No s\'està carregant"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Opció activada per l\'administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Opció desactivada per l\'administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Pàgina d\'inici de configuració"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index e79e02c0b020..6ee90b4c6ff6 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Použít kontrolu HDCP pouze pro obsah DRM"</item>
<item msgid="45075631231212732">"Vždy používat kontrolu HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (výchozí)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Použít systémový výběr (výchozí)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimalizováno pro kvalitu zvuku (990 kb/s / 909 kb/s)"</item>
- <item msgid="2921767058740704969">"Vyvážená kvalita zvuku a připojení (660 kb/s / 606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optimalizováno pro kvalitu připojení (330 kb/s / 303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimalizováno pro kvalitu zvuku"</item>
- <item msgid="4327143584633311908">"Vyvážená kvalita zvuku a připojení"</item>
- <item msgid="4681409244565426925">"Optimalizováno pro kvalitu připojení"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Vypnuto"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index f79bd20fe170..709030ae76fa 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Připojení nebude automaticky navázáno"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nebyl zjištěn žádný přístup k internetu"</string>
<string name="saved_network" msgid="4352716707126620811">"Uloženo uživatelem <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky připojeno přes poskytovatele %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Připojeno prostřednictvím %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Ultra rychlá"</item>
<item msgid="9085102246155045744">"Nejrychlejší"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Vyberte profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Osobní"</string>
<string name="category_work" msgid="8699184680584175622">"Pracovní"</string>
<string name="development_settings_title" msgid="215179176067683667">"Pro vývojáře"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Sítě"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikace bezdrát. displeje"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné protokolování Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivní předání z Wi-Fi na mobilní síť"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povolit Wi-Fi roaming"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázat absolutní hlasitost"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verze profilu Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Vyberte verzi profilu Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio – kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Vyberte zvukový kodek Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio – vzorkovací frekvence"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamování: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Pokud je tato možnost zapnuta, bude síť Wi-Fi při předávání datového připojení mobilní síti při slabém signálu Wi-Fi agresivnější."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Povolí nebo zakáže Wi-Fi roaming na základě množství datového provozu na rozhraní."</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávací paměť protokol. nástroje"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Velikost vyrovnávací paměti protokol. nástroje"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g> (přibližně)"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – plně se nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – pomocí adaptéru se plně nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – přes USB se plně nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – bezdrátově se plně nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznámé"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Spravováno administrátorem"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Povoleno administrátorem"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Zakázáno administrátorem"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Domovská stránka Nastavení"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 299f9cd2c385..4e40a35d6311 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Brug kun HDCP-kontrol ved DRM-indhold"</item>
<item msgid="45075631231212732">"Brug altid HDCP-kontrol"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Brug systemvalg (standard)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimeret til lydkvalitet (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Afbalancer lyd- og forbindelseskvalitet (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimeret til forbindelseskvalitet (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimeret til lydkvalitet"</item>
- <item msgid="4327143584633311908">"Afbalancer lyd- og forbindelseskvalitet"</item>
- <item msgid="4681409244565426925">"Optimeret til forbindelseskvalitet"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Fra"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index fda5fa2ea467..203ac00c0222 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Der oprettes ikke automatisk forbindelse"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ingen internetadgang"</string>
<string name="saved_network" msgid="4352716707126620811">"Gemt af <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisk tilsluttet via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tilsluttet via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Ekstra lynhurtig"</item>
<item msgid="9085102246155045744">"Hurtigst"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Vælg profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personlig"</string>
<string name="category_work" msgid="8699184680584175622">"Arbejde"</string>
<string name="development_settings_title" msgid="215179176067683667">"Indstillinger for udviklere"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netværk"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificering af trådløs skærm"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivér detaljeret Wi-Fi-logføring"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Tvungen skift fra Wi-Fi til mobildata"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillad altid scanning af Wi-Fi-roaming"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiver absolut lydstyrke"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version for Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Vælg AVRCP-version for Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-lydcodec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Vælg codec for Bluetooth-lyd"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Eksempelfrekvens for Bluetooth-lyd"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamer: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Når dette er aktiveret, gennemtvinges en overdragelse af dataforbindelsen fra Wi-Fi til mobilnetværk, når Wi-Fi-signalet er svagt"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Tillad/forbyd scanning i forbindelse med Wi-Fi-roaming afhængigt af mængden af datatrafik i grænsefladen"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Størrelser for Logger-buffer"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Vælg Logger-størrelser pr. logbuffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet (via stikkontakt)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet (via USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet (via trådløs)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ukendt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Oplader ikke"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fuld"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolleret af administratoren"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Aktiveret af administratoren"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Deaktiveret af administratoren"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Startside for Indstillinger"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 7e199b4a62f5..28dabb3305aa 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP-Prüfung nur für DRM-Inhalte verwenden"</item>
<item msgid="45075631231212732">"HDCP-Prüfung immer verwenden"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Standard)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Systemauswahl verwenden (Standard)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Für Audioqualität optimiert (990 kbit/s/909 kbit/s)"</item>
- <item msgid="2921767058740704969">"Ausgeglichene Audio- und Verbindungsqualität (660 kbit/s/606 kbit/s)"</item>
- <item msgid="8860982705384396512">"Für Verbindungsqualität optimiert (330 kbit/s/303 kbit/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Für Audioqualität optimiert"</item>
- <item msgid="4327143584633311908">"Ausgeglichene Audio- und Verbindungsqualität"</item>
- <item msgid="4681409244565426925">"Für Verbindungsqualität optimiert"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Aus"</item>
<item msgid="1593289376502312923">"64.000"</item>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index b43f6a081cf3..a07d4e910a5f 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Kein automatischer Verbindungsaufbau"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Kein Internetzugriff"</string>
<string name="saved_network" msgid="4352716707126620811">"Gespeichert von <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisch über %1$s verbunden"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Über %1$s verbunden"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Sehr schnell"</item>
<item msgid="9085102246155045744">"Am schnellsten"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profil auswählen"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Nutzer"</string>
<string name="category_work" msgid="8699184680584175622">"Geschäftlich"</string>
<string name="development_settings_title" msgid="215179176067683667">"Entwickleroptionen"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netzwerke"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Kabellose Übertragung"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ausführliche WLAN-Protokolle aktivieren"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressives Handover von WLAN an Mobilfunk"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"WLAN-Roamingsuchen immer zulassen"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Maximallautstärke deaktivieren"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP-Version auswählen"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-Audio-Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth-Audio-Codec auswählen"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth-Audio-Abtastrate"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wenn diese Option aktiviert ist, ist das WLAN bei schwachem Signal bei der Übergabe der Datenverbindung an den Mobilfunk aggressiver"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"WLAN-Roamingsuchen je nach Umfang des Datentraffics an der Schnittstelle zulassen bzw. nicht zulassen"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger-Puffergrößen"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Größe pro Protokollpuffer wählen"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Noch ca. <xliff:g id="TIME">%1$s</xliff:g> verbleibend"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Noch <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ungefähr noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig geladen"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig am Stromnetz geladen"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig über USB geladen"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis drahtlos vollständig geladen"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unbekannt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Durch den Administrator verwaltet"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Vom Administrator aktiviert"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Vom Administrator deaktiviert"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Startseite \"Einstellungen\""</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index fdbece744d25..6987b9ae3b96 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Χρήση ελέγχου HDCP μόνο για περιεχόμενο DRM"</item>
<item msgid="45075631231212732">"Να χρησιμοποιείται πάντα έλεγχος HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Προεπιλογή)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Μονοφωνικό"</item>
<item msgid="8883739882299884241">"Στερεοφωνικό"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Βελτιστοποιημένο για ποιότητα ήχου (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Ισορροπημένος ήχος και ποιότητα σύνδεσης (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Βελτιστοποιημένο για ποιότητα σύνδεσης (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Βελτιστοποιημένο για ποιότητα ήχου"</item>
- <item msgid="4327143584633311908">"Ισορροπημένος ήχος και ποιότητα σύνδεσης"</item>
- <item msgid="4681409244565426925">"Βελτιστοποιημένο για ποιότητα σύνδεσης"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Ανενεργό"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index a614a3026704..0632c7b24992 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Δεν θα συνδεθεί αυτόματα"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Δεν υπάρχει πρόσβαση στο διαδίκτυο"</string>
<string name="saved_network" msgid="4352716707126620811">"Αποθηκεύτηκε από <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Συνδέθηκε αυτόματα μέσω %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Συνδέθηκε μέσω %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Εξαιρετικά ταχεία"</item>
<item msgid="9085102246155045744">"Ταχύτατη"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Επιλογή προφίλ"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Προσωπικό"</string>
<string name="category_work" msgid="8699184680584175622">"Εργασία"</string>
<string name="development_settings_title" msgid="215179176067683667">"Επιλογές για προγραμματιστές"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Δικτύωση"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Πιστοποίηση ασύρματης οθόνης"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ενεργοποίηση λεπτομερ. καταγραφής Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Επιθ.μεταβ. Wi-Fi σε δίκτυο κιν.τηλ."</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Να επιτρέπεται πάντα η σάρωση Wi-Fi κατά την περιαγωγή"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Απενεργοποίηση απόλυτης έντασης"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Έκδοση AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Επιλογή έκδοσης AVRCP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Κωδικοποιητής ήχου Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Επιλογή κωδικοποιητή ήχου Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Ρυθμός δειγματοληψίας ήχου Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Ροή: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Όταν είναι ενεργό, το Wi-Fi θα μεταβιβάζει πιο επιθετικά τη σύνδ.δεδομένων σε δίκτυο κινητής τηλ., όταν το σήμα Wi-Fi είναι χαμηλό"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Να επιτρέπεται/να μην επιτρέπεται η σάρωση Wi-Fi κατά την περιαγωγή, βάσει της ποσότητας επισκεψιμότητας δεδομένων στη διεπαφή"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Μέγεθος αρχείων κατ/φής ανά προ/νή μνήμη αρχείου κατ/φής"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Απομένει/ουν <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένει/ουν <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση με AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση μέσω USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση ασύρματα"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Άγνωστο"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ελέγχονται από το διαχειριστή"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Ενεργοποιήθηκε από το διαχειριστή"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Απενεργοποιήθηκε από το διαχειριστή"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Αρχική σελίδα ρυθμίσεων"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 9e125e7b7b0e..1bc7b8c2b515 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Use System Selection (Default)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimised for Audio Quality (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimised for Connection Quality (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimised for Audio Quality"</item>
- <item msgid="4327143584633311908">"Balanced Audio and Connection Quality"</item>
- <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Off"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index ad6eae9f63be..04c51eaba53d 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
<string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Very rapid"</item>
<item msgid="9085102246155045744">"Fastest"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Work"</string>
<string name="development_settings_title" msgid="215179176067683667">"Developer options"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Enabled by administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Disabled by administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Settings Home"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 9e125e7b7b0e..1bc7b8c2b515 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Use System Selection (Default)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimised for Audio Quality (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimised for Connection Quality (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimised for Audio Quality"</item>
- <item msgid="4327143584633311908">"Balanced Audio and Connection Quality"</item>
- <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Off"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index ad6eae9f63be..04c51eaba53d 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
<string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Very rapid"</item>
<item msgid="9085102246155045744">"Fastest"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Work"</string>
<string name="development_settings_title" msgid="215179176067683667">"Developer options"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Enabled by administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Disabled by administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Settings Home"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 9e125e7b7b0e..1bc7b8c2b515 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Use System Selection (Default)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimised for Audio Quality (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimised for Connection Quality (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimised for Audio Quality"</item>
- <item msgid="4327143584633311908">"Balanced Audio and Connection Quality"</item>
- <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Off"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index ad6eae9f63be..04c51eaba53d 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
<string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Very rapid"</item>
<item msgid="9085102246155045744">"Fastest"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Work"</string>
<string name="development_settings_title" msgid="215179176067683667">"Developer options"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Enabled by administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Disabled by administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Settings Home"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index b97675456da3..ed30bace293b 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Usar comprobación HDCP para contenido DRM solamente"</item>
<item msgid="45075631231212732">"Siempre utilizar comprobación HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Usar selección del sistema (predeterminado)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estéreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizado para la calidad de audio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Calidad de audio y conexión equilibrada (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimizado para la calidad de conexión (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizado para la calidad de audio"</item>
- <item msgid="4327143584633311908">"Calidad de audio y conexión equilibrada"</item>
- <item msgid="4681409244565426925">"Optimizado para calidad de conexión"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Desactivado"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 4ce3bc22a28f..e0c911b3f5b8 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se conectará automáticamente"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"No se detectó acceso a Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Guardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conexión automática mediante %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conexión a través de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Muy rápida"</item>
<item msgid="9085102246155045744">"A velocidad máxima"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Elegir perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Trabajo"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opciones del programador"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro detallado de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Priorizar cambio de red Wi-Fi a móvil"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión de AVRCP del Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona la versión de AVRCP del Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Códec del audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Seleccionar códec del audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Frecuencia de muestreo del audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmitiendo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si habilitas esta opción, se priorizará el cambio de Wi-Fi a datos móviles cuando la señal de Wi-Fi sea débil"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/no permitir las búsquedas de Wi-Fi basadas la cantidad de tráfico de datos presente en la interfaz"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de Logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Selecciona el tamaño del Logger por búfer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Falta <xliff:g id="TIME">%1$s</xliff:g> aproximadamente"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga)"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga por CA)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga por USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta completar la carga inalámbrica)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Habilitada por el administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Inhabilitada por el administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Pantalla de configuración"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 1bc0098bbc21..7c1528f56abb 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utilizar comprobación de HDCP solo para contenido DRM"</item>
<item msgid="45075631231212732">"Utilizar siempre comprobación de HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Predeterminada)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Usar preferencia del sistema (predeter.)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estéreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizado para la calidad del audio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Equilibrar la calidad del audio y de la conexión (660/606&amp;nbsp;kbps)"</item>
- <item msgid="8860982705384396512">"Optimizado para la calidad de la conexión (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Se ha optimizado para la calidad del audio"</item>
- <item msgid="4327143584633311908">"Equilibrar la calidad del audio y la de la conexión"</item>
- <item msgid="4681409244565426925">"Se ha optimizado para la calidad de la conexión"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"No"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index d9347a361f58..3506f62d481e 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se establecerá conexión automáticamente"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"No se ha detectado acceso a Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Guardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectada automáticamente a través de %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Hiperrrápida"</item>
<item msgid="9085102246155045744">"La más rápida"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Seleccionar perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Trabajo"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opciones de desarrollo"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro Wi-Fi detallado"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferencia total de Wi-Fi a móvil"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP del Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona la versión AVRCP del Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Códec de audio por Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecciona el códec de audio por Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Porcentaje de muestreo de audio por Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de logging de Wi-Fi, mostrar por SSID RSSI en el selector Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si está habilitada, la conexión Wi-Fi será más agresiva al transferir la conexión de datos al móvil (si la señal Wi-Fi es baja)"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/No permitir búsquedas de Wi-Fi basadas en la cantidad de tráfico de datos presente en la interfaz"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de registrador"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Elige el tamaño del Logger por búfer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Tiempo restante (aproximado): <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - tiempo aproximado restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga con CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga con USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga inalámbrica"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se está cargando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Habilitado por el administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Inhabilitado por el administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Página principal de ajustes"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index db58188f37ee..f7a70003a24d 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Kasuta HDCP-kontrolli ainult DRM-sisu korral"</item>
<item msgid="45075631231212732">"Kasuta alati HDCP-kontrollimist"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (vaikeseade)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Süsteemi valiku kasutamine (vaikeseade)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Helikvaliteedi jaoks optimeeritud (990/909 kbit/s)"</item>
- <item msgid="2921767058740704969">"Tasakaalustatud heli- ja ühenduskvaliteet (660/606 kbit/s)"</item>
- <item msgid="8860982705384396512">"Ühenduskvaliteedi jaoks optimeeritud (330/303 kbit/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Helikvaliteedi jaoks optimeeritud"</item>
- <item msgid="4327143584633311908">"Tasakaalustatud heli- ja ühenduskvaliteet"</item>
- <item msgid="4681409244565426925">"Ühenduskvaliteedi jaoks optimeeritud"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Väljas"</item>
<item msgid="1593289376502312923">"64 000"</item>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index d643d9078f95..044389209e38 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automaatselt ei ühendata"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Interneti-ühendus puudub"</string>
<string name="saved_network" msgid="4352716707126620811">"Salvestas: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ühendus loodi automaatselt teenusega %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Ühendatud üksuse %1$s kaudu"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Väga tormakas"</item>
<item msgid="9085102246155045744">"Kõige kiirem"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profiili valimine"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Isiklik"</string>
<string name="category_work" msgid="8699184680584175622">"Töö"</string>
<string name="development_settings_title" msgid="215179176067683667">"Arendaja valikud"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Võrgustik"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Juhtmeta ekraaniühenduse sertifitseerimine"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Luba WiFi paljusõnaline logimine"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agress. üleminek WiFi-lt mobiilsidele"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luba alati WiFi-rändluse skannimine"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilne andmeside on alati aktiivne"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Keela absoluutne helitugevus"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothi AVRCP versioon"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Valige Bluetoothi AVRCP versioon"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetoothi heli kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Valige Bluetoothi helikodek"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetoothi heli diskreetimissagedus"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Voogesitus: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kui seade on lubatud, asendatakse nõrga signaaliga WiFi-ühendus agressiivsemalt mobiilse andmesideühendusega"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Luba/keela WiFi-rändluse skannimine liidese andmeliikluse põhjal"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logija puhvri suurused"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Vali logija suur. logipuhvri kohta"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – umbes <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni vahelduvvooluvõrgus"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni USB kaudu"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadim. juhtmeta ühenduse kaudu"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tundmatu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Juhib administraator"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Administraator on lubanud"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Administraator on keelanud"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Seadete avaleht"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 601bdea1cf0d..4214ea1ef81e 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Erabili HDCP egiaztapena DRM edukirako soilik"</item>
<item msgid="45075631231212732">"Erabili beti HDCP egiaztapena"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (lehenetsia)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Erabili sistema-hautapena (lehenetsia)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Monoa"</item>
<item msgid="8883739882299884241">"Estereoa"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Audioaren kalitatea areagotzeko optimizatua (990 Kb/s / 909 Kb/s)"</item>
- <item msgid="2921767058740704969">"Audioaren eta konexioaren kalitate orekatua (660 Kb/s / 606 Kb/s)"</item>
- <item msgid="8860982705384396512">"Konexioaren kalitatea areagotzeko optimizatua (330 Kb/s / 303 Kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Audioaren kalitatea areagotzeko optimizatua"</item>
- <item msgid="4327143584633311908">"Orekatu audioaren eta konexioaren kalitateak"</item>
- <item msgid="4681409244565426925">"Konexioaren kalitatea areagotzeko optimizatua"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Desaktibatuta"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6556a485e3d5..9293ef4497e0 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ez da konektatuko automatikoki"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ezin da konektatu Internetera"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s bidez automatikoki konektatuta"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s bidez konektatuta"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Oso bizkorra"</item>
<item msgid="9085102246155045744">"Bizkorrena"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Aukeratu profila"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Pertsonalak"</string>
<string name="category_work" msgid="8699184680584175622">"Lanekoak"</string>
<string name="development_settings_title" msgid="215179176067683667">"Garatzaileen aukerak"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Sareak"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Hari gabeko bistaratze-egiaztatzea"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Gaitu Wi-Fi sareetan saioa hasteko modu xehatua"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Behartu Wi-Fi konexiotik datuenera aldatzera"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Onartu beti ibiltaritzan Wi-Fi sareak bilatzea"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Datu-konexioa beti aktibo"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desgaitu bolumen absolutua"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP bertsioa"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Hautatu Bluetooth AVRCP bertsioa"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth bidezko audioaren kodeka"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Hautatu Bluetooth audioaren kodeka"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth bidezko audioaren lagin-abiadura"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Igortzean: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabeko bistaratze-egiaztapenaren aukerak"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago Wi-Fi sareetan saioa hasterakoan. Erakutsi sarearen identifikatzailea eta seinalearen indarra Wi‑Fi sareen hautagailuan."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Aukera hori gaituz gero, gailua nahitaez aldatuko da datu-konexiora Wi-Fi seinalea ahultzen dela nabaritutakoan"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Onartu edo debekatu ibiltaritzan Wi-Fi sareak bilatzea, interfazeko datu-trafikoaren arabera"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Erregistroen buffer-tamainak"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Hautatu erregistroen buffer-tamainak"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> inguru guztiz kargatu arte"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen dira"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> korronte bidez guztiz kargatu arte"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB bidez guztiz kargatu arte"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> haririk gabe guztiz kargatu arte"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ezezaguna"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzea"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administratzaileak kontrolatzen du"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Administratzaileak gaitu du"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Administratzaileak desgaitu du"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ezarpenen hasierako pantaila"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"% 0"</item>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 3dd6a3a54893..05bd6ca43cf2 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"‏استفاده از بررسی HDCP فقط برای محتوای DRM"</item>
<item msgid="45075631231212732">"‏همیشه از بررسی HDCP استفاده شود"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"‏AVRCP نسخه ۱.۴ (پیش‌فرض)"</item>
+ <item msgid="2089555299377409443">"‏AVRCP نسخه ۱.۵"</item>
+ <item msgid="2895327394279434278">"‏AVRCP نسخه ۱.۶"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"‏avrcp نسخه ۱۴"</item>
+ <item msgid="1913619118958233129">"‏avrcp نسخه ۱۵"</item>
+ <item msgid="7142710449249088270">"‏avrcp نسخه ۱۶"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"مونو"</item>
<item msgid="8883739882299884241">"استریو"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"بهینه‌شده برای کیفیت صوت (۹۹۰ کیلوبیت در ثانیه/۹۰۹ کیلوبیت در ثانیه)"</item>
- <item msgid="2921767058740704969">"کیفیت متعادل صوت و اتصال (۶۶۰ کیلوبیت در ثانیه/۶۰۶ کیلوبیت در ثانیه)"</item>
- <item msgid="8860982705384396512">"بهینه‌شده برای کیفیت اتصال (۳۳۰ کیلوبیت در ثانیه/۳۰۳ کیلوبیت در ثانیه)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"بهینه‌شده برای کیفیت صوت"</item>
- <item msgid="4327143584633311908">"کیفیت متعادل صوت و اتصال"</item>
- <item msgid="4681409244565426925">"بهینه‌شده برای کیفیت اتصال"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"خاموش"</item>
<item msgid="1593289376502312923">"۶۴ هزار"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index df66a1a43cb2..0cc42df5e95c 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"اتصال به‌صورت خودکار انجام نمی‌شود"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"دسترسی به اینترنت وجود ندارد"</string>
<string name="saved_network" msgid="4352716707126620811">"ذخیره‌شده توسط <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"‏اتصال خودکار ازطریق %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"‏متصل از طریق %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"‏در دسترس از طریق %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"خیلی تند"</item>
<item msgid="9085102246155045744">"سریع‌ترین"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"انتخاب نمایه"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"شخصی"</string>
<string name="category_work" msgid="8699184680584175622">"محل کار"</string>
<string name="development_settings_title" msgid="215179176067683667">"گزینه‌های برنامه‌نویسان"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"شبکه"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"گواهینامه نمایش بی‌سیم"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"‏فعال کردن گزارش‌گیری طولانی Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏Wi‑Fi قوی برای واگذاری به دستگاه همراه"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏اسکن‌های رومینگ Wi‑Fi همیشه مجاز است"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"غیرفعال کردن میزان صدای مطلق"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏نسخه AVRCP بلوتوث"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"‏انتخاب نسخه AVRCP بلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"کدک بلوتوث صوتی"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"انتخاب کدک صوتی بلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"سرعت نمونه بلوتوث صوتی"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"پخش جریانی: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"نمایش گزینه‌ها برای گواهینامه نمایش بی‌سیم"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏افزایش سطح گزارش‌گیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخاب‌کننده Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"‏زمانی‌که فعال است، درشرایطی که سیگنال Wi-Fi ضعیف باشد، Wi‑Fi برای واگذاری اتصال داده به دستگاه همراه قوی‌تر عمل خواهد کرد."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"‏مجاز/غیرمجاز کردن اسکن‌های رومینگ Wi‑Fi براساس مقدار ترافیک داده موجود در واسط"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"اندازه‌های حافظه موقت ثبت‌کننده"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"انتخاب اندازه‌ ثبت‌کننده در حافظه موقت ثبت"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی مانده"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی مانده"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل ازطریق برق متناوب"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل ازطریق USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل به‌صورت بی‌سیم"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ناشناس"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمی‌شود"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"توسط سرپرست سیستم کنترل می‌شود"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"سرپرست آن را فعال کرده است"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"سرپرست آن را غیرفعال کرده است"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"صفحه اصلی تنظیمات"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"٪۰"</item>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index dee7555a36e9..be638ba0a8e7 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Käytä HDCP-tarkistusta vain DRM-suojatulle sisällölle"</item>
<item msgid="45075631231212732">"Käytä aina HDCP-tarkistusta"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (oletus)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Käytä järjestelmän valintaa (oletus)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimoi äänenlaatu (990 kb/s / 909 kb/s)"</item>
- <item msgid="2921767058740704969">"Tasapainoinen yhteyden ja äänenlaadun optimointi (660 kb/s / 606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optimoi yhteyden laatu (330 kb/s / 303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimoi äänenlaatu"</item>
- <item msgid="4327143584633311908">"Tasapainoinen yhteyden ja äänenlaadun optimointi"</item>
- <item msgid="4681409244565426925">"Optimoi yhteyden laatu"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Ei käytössä"</item>
<item msgid="1593289376502312923">"64 kt"</item>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index ff88d1c97b45..3b008bfe5780 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Yhteyttä ei muodosteta automaattisesti"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ei internetyhteyttä"</string>
<string name="saved_network" msgid="4352716707126620811">"Tallentaja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaattinen yhteys muodostettu palvelun %1$s kautta"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Yhdistetty seuraavan kautta: %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Erittäin nopea"</item>
<item msgid="9085102246155045744">"Nopein"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Valitse profiili"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Henkilökohtainen"</string>
<string name="category_work" msgid="8699184680584175622">"Työ"</string>
<string name="development_settings_title" msgid="215179176067683667">"Kehittäjäasetukset"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Yhteysominaisuudet"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Langattoman näytön sertifiointi"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Käytä Wi-Fin laajennettua lokikirjausta"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Vaihda herkästi Wi-Fi mobiiliyhteyteen"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Salli Wi-Fi-verkkovierailuskannaus aina"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Poista yleinen äänenvoimakkuuden säätö käytöstä"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothin AVRCP-versio"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Valitse Bluetoothin AVRCP-versio"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-äänen koodekki"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Valitse Bluetooth-äänen koodekki"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth-ääninäytteen siirtonopeus"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Striimaus: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kun asetus on käytössä, datayhteys siirtyy helpommin Wi-Fistä matkapuhelinverkkoon, jos Wi-Fi-signaali on heikko."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Salli/estä Wi-Fi-verkkovierailuskannaus liittymässä esiintyvän dataliikenteen perusteella."</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Lokipuskurien koot"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Valitse puskurikohtaiset lokikoot"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen (laturi)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen (USB-lataus)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen (langaton lataus)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tuntematon"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Järjestelmänvalvojan käyttöön ottama"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Järjestelmänvalvojan käytöstä poistama"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Asetusten etusivu"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index f704ea44753d..8a9fbddfced0 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu GDN"</item>
<item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Utiliser sélect. du système (par défaut)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stéréo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimisé pour la qualité audio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Qualité audio et de la connexion équilibrée (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimisé pour la qualité de connexion (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimisé pour la qualité audio"</item>
- <item msgid="4327143584633311908">"Qualité audio et de la connexion équilibrée"</item>
- <item msgid="4681409244565426925">"Optimisé pour la qualité de connexion"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Désactivé"</item>
<item msgid="1593289376502312923">"64 ko"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index ae57852e522b..e9d882ee81b5 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Enregistrés par <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiquement connecté par %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté par %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Très rapide"</item>
<item msgid="9085102246155045744">"La plus rapide"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Sélectionnez un profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personnel"</string>
<string name="category_work" msgid="8699184680584175622">"Travail"</string>
<string name="development_settings_title" msgid="215179176067683667">"Options pour les développeurs"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Réseautage"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certification de l\'affichage sans fil"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. données Wi-Fi détaillées"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé du Wi-Fi aux données cell."</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version du profil Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Sélectionner la version du profil Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Sélectionner le codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taux d\'échantillonnage pour l\'audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si cette option est activée, le passage du Wi-Fi aux données cellulaires est forcé lorsque le signal Wi-Fi est faible"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Autoriser ou non la détection de réseaux Wi-Fi en itinérance en fonction de l\'importance du transfert de données dans l\'interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des mémoires tampons d\'enregistreur"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Tailles enreg. par tampon journal"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sur courant"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à charge complète par USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à charge complète sans fil"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Activé par l\'administrateur"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Désactivé par l\'administrateur"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Accueil des paramètres"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 22b11eab9f41..8b6fb0430b53 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu DRM"</item>
<item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Utiliser sélection système (par défaut)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stéréo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimisée pour la qualité audio (990/909 kbit/s)"</item>
- <item msgid="2921767058740704969">"Qualité audio et de la connexion équilibrée (660/606 kbit/s)"</item>
- <item msgid="8860982705384396512">"Optimisée pour la qualité de la connexion (330/303 kbit/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimisée pour la qualité audio"</item>
- <item msgid="4327143584633311908">"Qualité audio et de la connexion équilibrée"</item>
- <item msgid="4681409244565426925">"Optimisée pour la qualité de la connexion"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Désactivé"</item>
<item msgid="1593289376502312923">"64 Ko"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ede81d3c6526..b9f814fc0cc7 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Enregistré par <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connecté automatiquement via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Très rapide"</item>
<item msgid="9085102246155045744">"La plus rapide"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Sélectionner un profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personnel"</string>
<string name="category_work" msgid="8699184680584175622">"Professionnel"</string>
<string name="development_settings_title" msgid="215179176067683667">"Options pour les développeurs"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Mise en réseau"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certification affichage sans fil"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. infos Wi-Fi détaillées"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé Wi-Fi vers données mobiles"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Sélectionner la version Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Sélectionner le codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taux d\'échantillonnage audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options de la certification de l\'affichage sans fil"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler plus infos Wi-Fi, afficher par RSSI de SSID dans outil sélection Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si cette option est activée, le passage du Wi-Fi aux données mobiles est forcé en cas de signal Wi-Fi faible."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Autoriser ou non la détection de réseaux Wi-Fi en itinérance en fonction de l\'importance du trafic de données dans l\'interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tailles mémoires tampons enregistr."</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Tailles enreg. par tampon journal"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>."</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - encore environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant une charge complète"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sur secteur"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sur USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> avant charge complète sans fil"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Activé par l\'administrateur"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Désactivé par l\'administrateur"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Paramètres"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 19fd7fe5e292..2e55bf465deb 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utiliza a comprobación HDCP só para contido DRM"</item>
<item msgid="45075631231212732">"Utilizar sempre a comprobación HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Usar selección sistema (predeterminado)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estéreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizado para a calidade do audio (990 kb/s ou 909 kb/s)"</item>
- <item msgid="2921767058740704969">"Calidade equilibrada do audio e da conexión (660 kb/s ou 606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optimizado para a calidade da conexión (330 kb/s ou 303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizado para a calidade do audio"</item>
- <item msgid="4327143584633311908">"Calidade equilibrada do audio e da conexión"</item>
- <item msgid="4681409244565426925">"Optimizado para a calidade da conexión"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Desactivado"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index e6d48c2f97e5..8d5254c2f5ce 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Non se conectará automaticamente"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Non hai acceso a Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Redes gardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectada automaticamente a través de %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Moi rápido"</item>
<item msgid="9085102246155045744">"O máis rápido"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Seleccionar perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Persoal"</string>
<string name="category_work" msgid="8699184680584175622">"Traballo"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opcións de programador"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificado de visualización sen fíos"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Activar rexistro detallado da wifi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Entrega agresiva de wifi a móbil"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre buscas de itinerancia da wifi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactivar volume absoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP de Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecciona a versión AVRCP de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Códec de audio por Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Seleccionar códec de audio por Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de mostraxe de audio por Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Reprodución en tempo real: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nivel de rexistro da wifi, mostrar por SSID RSSI no selector de wifi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Cando estea activada esta función, a wifi será máis agresiva ao entregar a conexión de datos ao móbil, se o sinal wifi é feble"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/Non permitir buscas de itinerancia da wifi baseadas na cantidade de tráfico de datos presente na interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de rexistrador"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Seleccionar tamaños por búfer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Duración aproximada de <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante aproximado: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo por CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo por USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo sen fíos"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Opción controlada polo administrador"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Activado polo administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Desactivado polo administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Inicio da configuración"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 55c4092691a4..ca821cade285 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"ફક્ત DRM સામગ્રી માટે HDCP તપાસનો ઉપયોગ કરો"</item>
<item msgid="45075631231212732">"હંમેશા HDCP તપાસનો ઉપયોગ કરો"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ડિફૉલ્ટ)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"મૉનો"</item>
<item msgid="8883739882299884241">"સ્ટીરિઓ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ઑડિઓની ગુણવત્તા (990 kbps/909 kbps) માટે ઓપ્ટિમાઇઝ કર્યું"</item>
- <item msgid="2921767058740704969">"સંતુલિત ઑડિઓ અને કનેક્શનની ગુણવત્તા (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"કનેક્શનની ગુણવત્તા (330 kbps/303 kbps) માટે ઓપ્ટિમાઇઝ કર્યું"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ઑડિઓની ગુણવત્તા માટે ઓપ્ટિમાઇઝ કર્યું"</item>
- <item msgid="4327143584633311908">"સંતુલિત ઑડિઓ અને કનેક્શનની ગુણવત્તા"</item>
- <item msgid="4681409244565426925">"કનેક્શનની ગુણવત્તા માટે ઓપ્ટિમાઇઝ કર્યું"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"બંધ"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index bf66980b4286..60c1fbb41d79 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"આપમેળે કનેક્ટ કરશે નહીં"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા સચવાયું"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"ખૂબ જ તીવ્ર"</item>
<item msgid="9085102246155045744">"સૌથી ઝડપી"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"પ્રોફાઇલ પસંદ કરો"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"વ્યક્તિગત"</string>
<string name="category_work" msgid="8699184680584175622">"કાર્યાલય"</string>
<string name="development_settings_title" msgid="215179176067683667">"વિકાસકર્તાનાં વિકલ્પો"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"નેટવર્કિંગ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"બિનતારી પ્રદર્શન પ્રમાણન"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi વર્બોઝ લૉગિંગ સક્ષમ કરો"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"સશક્ત Wi‑Fiથી મોબાઇલ પર હૅન્ડઓવર"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"હંમેશા Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ચોક્કસ વૉલ્યૂમને અક્ષમ કરો"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP સંસ્કરણ"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP સંસ્કરણ પસંદ કરો"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth ઑડિઓ કોડેક"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth ઑડિઓ LDAC કોડેક પસંદ કરો"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth ઑડિઓ નમૂના દર"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"સ્ટ્રીમિંગ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi લોગિંગ સ્તર વધારો, Wi‑Fi પીકરમાં SSID RSSI દીઠ બતાવો"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"જ્યારે સક્ષમ કરેલ હોય, ત્યારે Wi‑Fi સિગ્નલ નબળું હોવા પર, Wi-Fi વધુ ઝડપથી ડેટા કનેક્શનને મોબાઇલ પર મોકલશે"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ઇન્ટરફેસ પર હાજર ડેટા ટ્રાફિકના પ્રમાણનાં આધારે Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો/નામંજૂર કરો"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"લૉગ દીઠ લૉગર કદ બફર પસંદ કરો"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"અંદાજે. <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - લગભગ <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC પર સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB પર સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - વાયરલેસ પરથી સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"અજાણ્યું"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"વ્યવસ્થાપક દ્વારા સક્ષમ કરેલ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"સેટિંગ્સ હોમ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 60d10120a482..d1878a7cf5f6 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -116,16 +116,8 @@
<item msgid="8900559293912978337">"मोनो"</item>
<item msgid="8883739882299884241">"स्टीरियो"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ऑडियो की गुणवत्ता के लिए अनुकूलित किया गया (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"संतुलित ऑडियो और कनेक्शन गुणवत्ता (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ऑडियो की गुणवत्ता के लिए अनुकूलित किया गया"</item>
- <item msgid="4327143584633311908">"संतुलित ऑडियो और कनेक्शन गुणवत्ता"</item>
- <item msgid="4681409244565426925">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"बंद"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index f1f2d3a5a97c..8d4935f9fca8 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -34,7 +34,7 @@
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string>
<!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
<skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string>
@@ -141,7 +141,8 @@
<item msgid="5194774745031751806">"अत्यधिक तीव्र"</item>
<item msgid="9085102246155045744">"सबसे तेज़"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"प्रोफ़ाइल चुनें"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string>
<string name="category_work" msgid="8699184680584175622">"कार्यालय"</string>
<string name="development_settings_title" msgid="215179176067683667">"डेवलपर विकल्प"</string>
@@ -353,8 +354,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"व्यवस्थापक द्वारा नियंत्रित"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"व्यवस्थापक द्वारा सक्षम किया गया"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"व्यवस्थापक द्वारा अक्षम किया गया"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"सेटिंग होम"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index b092a8ff896e..641b9fb204ac 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Upotrebljavaj HDCP provjeru samo za DRM sadržaj"</item>
<item msgid="45075631231212732">"Uvijek upotrebljavaj HDCP provjeru"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (zadano)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Upotreba odabira sustava (zadano)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizirano za kvalitetu audioreprodukcije (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Uravnotežena kvaliteta audioreprodukcije i veze (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimizirano za kvalitetu veze (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizirano za kvalitetu audioreprodukcije"</item>
- <item msgid="4327143584633311908">"Uravnotežena kvaliteta audioreprodukcije i veze"</item>
- <item msgid="4681409244565426925">"Optimizirano za kvalitetu veze"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Isključeno"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 291e37a63e61..18242e3e76c0 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se povezati automatski"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
<string name="saved_network" msgid="4352716707126620811">"Spremljeno: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezan putem %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Povezano putem %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Vrlo ubrzano"</item>
<item msgid="9085102246155045744">"Najbrže"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Odabir profila"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Osobno"</string>
<string name="category_work" msgid="8699184680584175622">"Posao"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opcije za razvojne programere"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući opširnu prijavu na Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aktivni prijelaz s Wi‑Fi na mob. mrežu"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopusti slobodno traženje Wi-Fi mreže"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući apsolutnu glasnoću"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija AVRCP-a za Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Odaberite verziju AVRCP-a za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodek za Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Odaberi kodek za Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorka za Bluetooth Audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strujanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaži opcije za certifikaciju bežičnog prikaza"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ako je omogućeno, Wi-Fi će aktivno prebacivati podatkovnu vezu mobilnoj mreži kada je Wi-Fi signal slab."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dopustite ili blokirajte slobodno traženje Wi-Fi mreža na temelju količine podatkovnog prometa na sučelju."</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međuspremnika zapisnika"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Odaberite veličinu međuspremnika zapisnika"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Još približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Još <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo je približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – još <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti putem utičnice"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti putem USB-a"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti bežičnim putem"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolira administrator"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Početni zaslon postavki"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 160e9ebadfd8..e647f8650f3f 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Csak DRM-tartalomhoz használjon HDCP ellenőrzést"</item>
<item msgid="45075631231212732">"Mindig használjon HDCP ellenőrzést"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (alapértelmezett)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Rendszerérték (alapértelmezett)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Monó"</item>
<item msgid="8883739882299884241">"Sztereó"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimális hangminőség (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Kiegyensúlyozott hang- és kapcsolatminőség (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimális kapcsolatminőség (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimális hangminőség"</item>
- <item msgid="4327143584633311908">"Kiegyensúlyozott hang- és kapcsolatminőség"</item>
- <item msgid="4681409244565426925">"Optimális kapcsolatminőség"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Ki"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 33e80348190d..f4b7dd0d0c06 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nem csatlakozik automatikusan"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nincs internet-hozzáférés"</string>
<string name="saved_network" msgid="4352716707126620811">"Mentette: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatikusan csatlakozott a következőn keresztül: %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Csatlakozva a következőn keresztül: %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Rendkívül gyors"</item>
<item msgid="9085102246155045744">"Leggyorsabb"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profil kiválasztása"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Személyes"</string>
<string name="category_work" msgid="8699184680584175622">"Munkahelyi"</string>
<string name="development_settings_title" msgid="215179176067683667">"Fejlesztői beállítások"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Hálózatok"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Vezeték nélküli kijelző tanúsítványa"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Részletes Wi-Fi-naplózás engedélyezése"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresszív Wi‑Fi–mobilhálózat átadás"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi-roaming ellenőrzésének engedélyezése mindig"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Abszolút hangerő funkció letiltása"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"A Bluetooth AVRCP-verziója"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"A Bluetooth AVRCP-verziójának kiválasztása"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth hang – Kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth hangkodek kiválasztása"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth hang – mintavételezési gyakoriság"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamelés: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ha engedélyezi, a Wi-Fi agresszívebben fogja átadni az adatkapcsolatot a mobilhálózatnak gyenge Wi-Fi-jel esetén"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"A Wi-Fi-roaming ellenőrzésének engedélyezése vagy letiltása az interfészen jelen lévő adatforgalom mennyiségétől függően"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Naplózási puffer mérete"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Naplózási pufferméret kiválasztása"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Kb. <xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - körülbelül <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a hálózati áramról való feltöltésig"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig USB-n"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a vezeték nélküli teljes feltöltésig"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ismeretlen"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nem töltődik"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Rendszergazda által irányítva"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Engedélyezve a rendszergazda által"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Letiltva a rendszergazda által"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Beállítások kezdőlapja"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 868735e9d843..0138d2ef177c 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Օգտագործել HDCP-ը` միայն DRM-ի բովանդակությունը ստուգելու համար"</item>
<item msgid="45075631231212732">"Միշտ օգտագործել HDCP ստուգումը"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (կանխադրված)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Մոնո"</item>
<item msgid="8883739882299884241">"Ստերեո"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Օպտիմալացված ձայնի որակի համար (990 կբ/վ / 909 կբ/վ)"</item>
- <item msgid="2921767058740704969">"Ձայնի և կապի հավասարակշռված որակ (660 կբ/վ / 606 կբ/վ)"</item>
- <item msgid="8860982705384396512">"Օպտիմալացված կապի որակի համար (330 կբ/վ / 303 կբ/վ)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Օպտիմալացված ձայնի որակի համար"</item>
- <item msgid="4327143584633311908">"Ձայնի և կապի հավասարակշռված որակ"</item>
- <item msgid="4681409244565426925">"Օպտիմալացված կապի որակի համար"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Անջատված է"</item>
<item msgid="1593289376502312923">"64ԿԲ"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index b06f8ddfe4f6..64ee1fce50dc 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Չի միանա ավտոմատ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ինտերնետ կապ չկա"</string>
<string name="saved_network" msgid="4352716707126620811">"Պահել է հետևյալ օգտատերը՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Չափազանց արագ"</item>
<item msgid="9085102246155045744">"Ամենաարագ"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Ընտրել պրոֆիլ"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Անձնական"</string>
<string name="category_work" msgid="8699184680584175622">"Աշխատանքային"</string>
<string name="development_settings_title" msgid="215179176067683667">"Ծրագրավորողի ընտրանքներ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Ցանց"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Անլար էկրանի վկայագրում"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Միացնել Wi‑Fi մանրամասն գրանցամատյանները"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi-ից կտրուկ անցում բջջային ինտերնետի"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Միշտ թույլատրել Wi‑Fi ռոումինգի որոնումը"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Անջատել ձայնի բացարձակ ուժգնությունը"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP տարբերակը"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Ընտրել Bluetooth AVRCP տարբերակը"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth աուդիո կոդեկ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Ընտրեք Bluetooth աուդիո կոդեկը"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth աուդիոյի Ընդհատավորման հաճախականությունը"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Հեռարձակում՝ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանի հավաստագրման ընտրանքները"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Եթե այս գործառույթը միացված է, Wi-Fi-ի թույլ ազդանշանի դեպքում Wi‑Fi ինտերնետից բջջային ինտերնետի անցումը ավելի կտրուկ կկատարվի"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Թույլատրել/արգելել Wi‑Fi ռոումինգի որոնումը՝ կախված միջերեսում տվյալների երթևեկի ծավալից"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Տեղեկամատյանի պահնակի չափերը"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Ընտրեք տեղեկամատյանի չափը մեկ պահնակի համար"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – մնացել է մոտ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնացել է <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև հոսանքից լրիվ լիցքավորումը"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև USB-ով լրիվ լիցքավորումը"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը անլար եղանակով"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Անհայտ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Միացված է ադմինիստրատորի կողմից"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Կասեցված է ադմինիստրատորի կողմից"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Կարգավորումների գլխավոր էջ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index b2f3891477da..5289d265e442 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Gunakan pemeriksaan HDCP untuk konten DRM saja"</item>
<item msgid="45075631231212732">"Selalu gunakan pemeriksaan HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Default)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Dioptimalkan untuk Kualitas Audio (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Kualitas Audio dan Sambungan Seimbang (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Dioptimalkan untuk Kualitas Sambungan for Connection Quality (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Dioptimalkan untuk Kualitas Audio"</item>
- <item msgid="4327143584633311908">"Kualitas Audio dan Sambungan Seimbang"</item>
- <item msgid="4681409244565426925">"Dioptimalkan untuk Kualitas Sambungan"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Nonaktif"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 5d8ecb210b0e..fe2840f2d29a 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Tidak akan tersambung otomatis"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Tidak ada akses internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Disimpan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Tersambung otomatis melalui %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Sangat cepat sekali"</item>
<item msgid="9085102246155045744">"Tercepat"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Pilih Profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Pribadi"</string>
<string name="category_work" msgid="8699184680584175622">"Kantor"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opsi developer"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Jaringan"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikasi layar nirkabel"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktifkan Pencatatan Log Panjang Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Pengalihan Wi-Fi Agresif ke seluler"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Selalu izinkan Pemindaian Roaming Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Data seluler selalu aktif"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Nonaktifkan volume absolut"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pilih Versi AVRCP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec Audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Pilih Codec Audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Frekuensi Sampel Audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Jika diaktifkan, Wi-Fi akan menjadi lebih agresif dalam mengalihkan sambungan data ke seluler saat sinyal Wi-Fi lemah"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Izinkan/Larang Pemindaian Roaming Wi-Fi berdasarkan jumlah lalu lintas data yang ada di antarmuka"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Ukuran penyangga pencatat log"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Ukuran Pencatat Log per penyangga log"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira tersisa <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tersisa"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tersisa"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh pada AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh melalui USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh dari nirkabel"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikontrol oleh admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Diaktifkan oleh administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Dinonaktifkan oleh administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Layar Utama Setelan"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index b9213f41c61f..0a1e19e1bb2b 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Nota HDCP-athugun aðeins fyrir höfundarréttarvarið efni"</item>
<item msgid="45075631231212732">"Nota alltaf HDCP-eftirlit"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (sjálfgefið)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Nota val kerfisins (sjálfgefið)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Einóma"</item>
<item msgid="8883739882299884241">"Víðóma"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Fínstillt fyrir hljóðgæði (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Jafnvægi á milli gæða hljóðs og tengingar (660 kbps / 606 kbps)"</item>
- <item msgid="8860982705384396512">"Fínstillt fyrir gæði tengingar (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Fínstillt fyrir hljóðgæði"</item>
- <item msgid="4327143584633311908">"Jafnvægi á milli gæða hljóðs og tengingar"</item>
- <item msgid="4681409244565426925">"Fínstillt fyrir gæði tengingar"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Slökkt"</item>
<item msgid="1593289376502312923">"64 k"</item>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d8a95581b013..5ef8087875fa 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Mun ekki tengjast sjálfkrafa"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Enginn netaðgangur"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> vistaði"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Sjálfkrafa tengt um %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tengt í gegnum %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Næsthraðast"</item>
<item msgid="9085102246155045744">"Hraðast"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Veldu snið"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Persónulegt"</string>
<string name="category_work" msgid="8699184680584175622">"Vinna"</string>
<string name="development_settings_title" msgid="215179176067683667">"Forritunarkostir"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netkerfi"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Vottun þráðlausra skjáa"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Kveikja á ítarlegri skráningu Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Hröð skipti úr Wi‑Fi í farsímagögn"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Leyfa alltaf reikileit með Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slökkva á samstillingu hljóðstyrks"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-útgáfa"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Velja Bluetooth AVRCP-útgáfu"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth hljóðkóðari"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Velja Bluetooth-hljóðkóðara"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth hljóðtökutíðni"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streymi: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Þegar þetta er virkt mun Wi-Fi skipta hraðar yfir í farsímagagnatengingu þegar Wi-Fi-tenging er léleg"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Leyfa/banna reikileit með Wi-Fi á grunni þess hversu mikil gagnaumferð er fyrir hendi í viðmótinu"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Annálsritastærðir biðminna"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Veldu annálsritastærðir á biðminni"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – um <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullri hleðslu er náð"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullhlaðið með hleðslutæki"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullhlaðið með USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullhlaðið þráðlaust"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Óþekkt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Stjórnað af kerfisstjóra"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Virkjað af stjórnanda"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Stjórnandi gerði óvirkt"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Stillingar"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index 0c46df4dbb57..da6b885d691f 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Usa la verifica HDCP solo per contenuti DRM"</item>
<item msgid="45075631231212732">"Usa sempre la verifica HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (predefinita)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Usa selezione di sistema (predefinita)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Ottimizzato per qualità audio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Audio bilanciato e qualità di connessione (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Ottimizzato per qualità di connessione (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Ottimizzato per qualità audio"</item>
- <item msgid="4327143584633311908">"Audio bilanciato e qualità di connessione"</item>
- <item msgid="4681409244565426925">"Ottimizzato per qualità di connessione"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Off"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 9858d3c5a9db..711971ef725a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Non verrà eseguita la connessione automatica"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nessun accesso a Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Salvata da <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Collegato automaticamente tramite %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Collegato tramite %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Molto rapida"</item>
<item msgid="9085102246155045744">"Massima velocità"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Scegli profilo"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personali"</string>
<string name="category_work" msgid="8699184680584175622">"Lavoro"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opzioni sviluppatore"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Reti"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificazione display wireless"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Attiva registrazione dettagliata Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi aggressivo per passaggio a cellulare"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Consenti sempre scansioni roaming Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disattiva volume assoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versione Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Seleziona versione Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Seleziona il codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Frequenza di campionamento audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta il livello di registrazione Wi-Fi, mostrando il SSID RSSI nel selettore Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Con questa impostazione attivata, il Wi-Fi è più aggressivo nel passare la connessione dati al cellulare, con segnale Wi-Fi basso"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Consenti/vieta scansioni roaming Wi-Fi basate sulla quantità di traffico dati presente a livello di interfaccia"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Dimensioni buffer Logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Seleziona dimensioni Logger per buffer log"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Circa <xliff:g id="TIME">%1$s</xliff:g> rimanenti"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ancora circa <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa con wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Sconosciuta"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Gestita dall\'amministratore"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Attivata dall\'amministratore"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Disattivata dall\'amministratore"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Home page Impostazioni"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index c918740a174f..f106a34fdb73 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"‏השתמש בבדיקת HDCP עבור תוכן DRM בלבד"</item>
<item msgid="45075631231212732">"‏תמיד השתמש בבדיקת HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"‏AVRCP 1.4 (ברירת המחדל)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"שימוש בבחירת המערכת (ברירת המחדל)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"מונו"</item>
<item msgid="8883739882299884241">"סטריאו"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"‏אופטימיזציה להשגת איכות אודיו מרבית (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"‏איזון בין איכות החיבור לאיכות אודיו (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"‏אופטימיזציה להשגת איכות חיבור מרבית (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"אופטימיזציה להשגת איכות אודיו מרבית"</item>
- <item msgid="4327143584633311908">"אזן בין איכות החיבור לאיכות אודיו"</item>
- <item msgid="4681409244565426925">"אופטימיזציה להשגת איכות חיבור מרבית"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"כבוי"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 4bea8a5bda7e..fedc9b6e1781 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"לא יתבצע חיבור באופן אוטומטי"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"אין גישה לאינטרנט"</string>
<string name="saved_network" msgid="4352716707126620811">"נשמר על ידי <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"‏מחובר אוטומטית דרך %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"‏מחובר דרך %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"‏זמינה דרך %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"יותר מהיר ממהיר במיוחד"</item>
<item msgid="9085102246155045744">"הכי מהיר"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"בחר פרופיל"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"אישי"</string>
<string name="category_work" msgid="8699184680584175622">"עבודה"</string>
<string name="development_settings_title" msgid="215179176067683667">"אפשרויות מפתח"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"תקשורת רשתות"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"‏אישור של תצוגת WiFi"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"‏הפעל רישום מפורט של Wi‑Fi ביומן"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏העברה אגרסיבית מ-Wi‑Fi לרשת סלולרית"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏התר תמיד סריקות נדידה של Wi‑Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"השבת עוצמת קול מוחלטת"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏Bluetooth גרסה AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"‏בחר Bluetooth גרסה AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"‏Codec אודיו ל-Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"‏בחירת ‏Codec אודיו ל-Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"‏קצב דגימה של אודיו ל-Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"סטרימינג: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"‏הצג אפשרויות עבור אישור של תצוגת WiFi"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"‏כשאפשרות זו מופעלת, Wi-Fi יתנהג בצורה אגרסיבית יותר בעת העברת חיבור הנתונים לרשת הסלולרית כשאות ה-Wi-Fi חלש."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"‏התר/מנע סריקות נדידה של Wi-Fi בהתבסס על נפח תנועת הנתונים הקיימת בממשק"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יוצר יומן"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"בחר גדלים של יוצר יומן לכל מאגר יומן"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"נשארו <xliff:g id="TIME">%1$s</xliff:g> בערך"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"נותרו <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - הזמן הנותר: בערך <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - נותרו <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה בזרם חילופין"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה באמצעות USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה בחיבור אלחוטי"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"הופעל על ידי מנהל המערכת"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"הושבת על ידי מנהל המערכת"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"דף הבית של ההגדרות"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 2b6004fe2d3c..18945ec8f6df 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRMコンテンツにのみHDCPチェックを使用する"</item>
<item msgid="45075631231212732">"HDCPチェックを常に使用する"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4(デフォルト)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"システムの選択(デフォルト)を使用"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"モノラル"</item>
<item msgid="8883739882299884241">"ステレオ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"音質重視で最適化(990 kbps / 909 kbps)"</item>
- <item msgid="2921767058740704969">"音質と接続の品質のバランスを確保(660 kbps / 606 kbps)"</item>
- <item msgid="8860982705384396512">"接続の品質重視で最適化(330 kbps / 303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"音質重視で最適化"</item>
- <item msgid="4327143584633311908">"音質と接続の品質のバランスを確保"</item>
- <item msgid="4681409244565426925">"接続の品質重視で最適化"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"OFF"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 267af1ae5efd..55c140c273c0 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"自動的に接続されません"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"インターネットに接続していません"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g>で保存"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s 経由で自動的に接続しています"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"非常に高速"</item>
<item msgid="9085102246155045744">"最高速"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"プロファイルの選択"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"個人用"</string>
<string name="category_work" msgid="8699184680584175622">"仕事用"</string>
<string name="development_settings_title" msgid="215179176067683667">"開発者向けオプション"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ネットワーク"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ワイヤレスディスプレイ認証"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi詳細ログの有効化"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi を強制的にモバイル接続に切り替える"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fiローミングスキャンを常に許可する"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"絶対音量を無効にする"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP バージョン"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP バージョンを選択する"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth オーディオ コーデック"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth オーディオ コーデックを選択"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth オーディオ サンプルレート"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ストリーミング: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ワイヤレスディスプレイ認証のオプションを表示"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ON にすると、Wi-Fi の電波強度が弱い場合は強制的にモバイルデータ接続に切り替わるようになります"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"インターフェースのデータトラフィック量に基づいたWi-Fiローミングスキャンを許可するかしないかを設定できます"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ログバッファのサイズ"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"各ログバッファのログサイズを選択"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g>(残り時間)"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>(残り時間)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>(AC)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>(USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>(ワイヤレス)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
@@ -355,8 +345,10 @@
<!-- no translation found for battery_info_status_full (2824614753861462808) -->
<skip />
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"管理者により管理されています"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"管理者によって有効にされています"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"管理者によって無効にされています"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"設定のホーム"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 2dd47d9a06a8..9c326a732145 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP შემოწმების გამოყენება მხოლოდ DRM კონტენტის შემთხვევაში"</item>
<item msgid="45075631231212732">"ყოველთვის გამოიყენე HDCP შემოწმება"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ნაგულისხმევი)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"მონო"</item>
<item msgid="8883739882299884241">"სტერეო"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"აუდიოს ხარისხისთვის ოპტიმიზებული (990/909 კბიტი/წმ)"</item>
- <item msgid="2921767058740704969">"აუდიოსა და კავშირის დაბალანსებული ხარისხი (660/606 კბიტი/წმ)"</item>
- <item msgid="8860982705384396512">"კავშირის ხარისხისთვის ოპტიმიზებული (330/303 კბიტი/წმ)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"აუდიოს ხარისხისთვის ოპტიმიზებული"</item>
- <item msgid="4327143584633311908">"აუდიოსა და კავშირის დაბალანსებული ხარისხი"</item>
- <item msgid="4681409244565426925">"კავშირის ხარისხისთვის ოპტიმიზებული"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"გამორთული"</item>
<item msgid="1593289376502312923">"64 კბაიტი"</item>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index ef8c6ba28dd2..abda1ddc024b 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ავტომატურად დაკავშირება ვერ მოხერხდება"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ინტერნეტთან კავშირი არ არის"</string>
<string name="saved_network" msgid="4352716707126620811">"შენახული <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"ავტომატურად დაკავშირდა %1$s-ის მეშვეობით"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ით დაკავშირებული"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"ძალიან ჩქარი"</item>
<item msgid="9085102246155045744">"უსწრაფესი"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"პროფილის არჩევა"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"პირადი"</string>
<string name="category_work" msgid="8699184680584175622">"სამსახური"</string>
<string name="development_settings_title" msgid="215179176067683667">"პარამეტრები დეველოპერებისთვის"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ქსელი"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"უსადენო ეკრანის სერტიფიცირება"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi-ს დაწვრილებითი აღრიცხვის ჩართვა"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi-ს მობ. ინტერნეტზე აგრესიული გადართვა"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Roam სკანირების მუდამ დაშვება"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ხმის აბსოლუტური სიძლიერის გათიშვა"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-ის AVRCP-ის ვერსია"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"აირჩიეთ Bluetooth-ის AVRCP-ის ვერსია"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth აუდიოს კოდეკი"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"აირჩიეთ Bluetooth აუდიოს კოდეკი"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth აუდიოს დისკრეტიზაციის სიხშირე"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"სტრიმინგი: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ჩართვის შემთხვევაში, Wi‑Fi უფრო აქტიურად შეეცდება მობილურ ინტერნეტზე გადართვას, როცა Wi‑Fi სიგნალი სუსტია"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Wifi Roam სკანირების დაშვება/აკრძალვა, ინტერფეისზე არსებული მონაცემთა ტრაფიკზე დაფუძნებით"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ჟურნალიზაციის ბუფერის ზომები"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"აირჩიეთ ჟურნ. ზომა / ჟურნ. ბუფერზე"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"დარჩენილია დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> — ელკვებით სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> — USB-ით სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ უსადენო დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"უცნობი"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"იმართება ადმინისტრატორის მიერ"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"ჩართულია ადმინისტრატორის მიერ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"გათიშულია ადმინისტრატორის მიერ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"პარამეტრების გვერდი"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 3f8bda2a5915..d4e23536f703 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP (кең жолақты сандық мазмұн қорғау) тексеруді DRM (авторлық құқықты техникалық қорғау) мазмұны үшін ғана қолданыңыз"</item>
<item msgid="45075631231212732">"Әрқашан HDCP (жоғары кең жолақты сандық мазмұн қорғаушы) тексерулерін қолданыңыз"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (әдепкі)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Жүйені таңдау (әдепкі)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Аудиомазмұн сапасы бойынша оңтайландырылды (990 кбит/сек не 909 кбит/сек)"</item>
- <item msgid="2921767058740704969">"Теңгерілген аудиомазмұн мен байланыс сапасы (660 кб/сек не 606 кб/сек)"</item>
- <item msgid="8860982705384396512">"Байланыс сапасы бойынша оңтайландырылды (330 кбит/сек не 303 кбит/сек)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Аудиомазмұн сапасы үшін оңтайландырылды"</item>
- <item msgid="4327143584633311908">"Теңгерілген аудиомазмұн мен байланыс сапасы"</item>
- <item msgid="4681409244565426925">"Байланыс сапасы бойынша оңтайландырылды"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Өшірулі"</item>
<item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index b43e82dfaaff..cacc9c60be75 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматты қосылмайды"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Интернетпен байланыс жоқ"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> сақтаған"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s арқылы автоматты қосылды"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s арқылы қосылған"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Өте тез"</item>
<item msgid="9085102246155045744">"Ең тез"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Профильді таңдау"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Жеке"</string>
<string name="category_work" msgid="8699184680584175622">"Жұмыс"</string>
<string name="development_settings_title" msgid="215179176067683667">"Әзірлеуші опциялары"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Желі орнату"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сымсыз дисплей сертификаты"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi егжей-тегжейлі журналға тір. қосу"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi желісінен мобильдік желіге ауысу"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi роумингін іздеулерге әрқашан рұқсат ету"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP нұсқасы"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP нұсқасын таңдау"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудимазмұн кодегі"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth аудиокодегін таңдау"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth аудиомазмұны бойынша үлгі жиілігі"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляция: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Сымсыз дисплей растау опцияларын көрсету"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi жур. тір. дең. арт., Wi‑Fi желісін таңдағышта әр SSID RSSI бойынша көрсету"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wi‑Fi сигналы әлсіз болғанда, деректер байланысы мәжбүрлі түрде мобильдік желіге ауысады"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Интерфейсте бар деректер трафигінің мөлшерінің негізінде Wi-Fi роумингін іздеулерге рұқсат ету/тыйым салу"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Журналға тіркеуші буферінің өлшемдері"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Әр журнал буфері үшін журналға тіркеуші өлшемдерін таңдау"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – желі арқылы толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – USB арқылы толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – сымсыз толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Белгісіз"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Әкімші басқарады"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Әкімші қосқан"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Әкімші өшірген"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Параметрлер негізгі беті"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 2ba33f4d99c1..5e6656b3a3bf 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"ប្រើ​ការ​ពិនិត្យ HDCP សម្រាប់​តែ​មាតិកា DRM ប៉ុណ្ណោះ"</item>
<item msgid="45075631231212732">"ប្រើ​ការ​ពិនិត្យ HDCP ជា​និច្ច"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (លំនាំដើម)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"ម៉ូ​ណូ"</item>
<item msgid="8883739882299884241">"ស្តេរ៉េអូ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"បាន​បង្កើន​ប្រសិទ្ធភាព​​សម្រាប់​គុណភាព​សំឡេង (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"សំឡេង​ដែល​មាន​តុល្យភាព និង​គុណភាព​នៃ​ការ​ត​ភ្ជាប់ (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"បាន​បង្កើន​ប្រសិទ្ធភាព​សម្រាប់​គុណភាព​​នៃ​ការ​ត​ភ្ជាប់ (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"បាន​បង្កើន​ប្រសិទ្ធភាពសម្រាប់​​គុណភាព​សំឡេង"</item>
- <item msgid="4327143584633311908">"សំឡេង​ដែល​មាន​តុល្យភាព និង​គុណភាព​នៃ​ការ​តភ្ជាប់"</item>
- <item msgid="4681409244565426925">"បាន​បង្កើន​ប្រសិទ្ធភាព​​សម្រាប់គុណភាព​នៃ​ការ​ត​ភ្ជាប់"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"បិទ"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index f59587813903..daa4c93c76b1 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"នឹងមិនភ្ជាប់ដោយស្វ័យប្រវត្តិទេ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"មិនមានអ៊ីនធឺណិតទេ"</string>
<string name="saved_network" msgid="4352716707126620811">"បានរក្សាទុកដោយ <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"បានភ្ជាប់ដោយស្វ័យប្រវត្តិតាមរយៈ %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"បានភ្ជាប់តាមរយៈ %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"រហ័សខ្លាំង"</item>
<item msgid="9085102246155045744">"លឿនបំផុត"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"ជ្រើសប្រវត្តិរូប"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ផ្ទាល់ខ្លួន"</string>
<string name="category_work" msgid="8699184680584175622">"កន្លែង​ធ្វើការ"</string>
<string name="development_settings_title" msgid="215179176067683667">"ជម្រើស​អ្នក​អភិវឌ្ឍ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ការភ្ជាប់បណ្ដាញ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"បង្ហាញ​ការ​កំណត់​រចនាសម្ព័ន្ធ​ឥត​ខ្សែ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"បើក​កំណត់ហេតុ​រៀបរាប់​វ៉ាយហ្វាយ"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ប្តូរទៅប្រើបណ្តាញចល័តពេល Wi‑Fi មានរលកសញ្ញាខ្លាំងពេក"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"តែងតែ​អនុញ្ញាត​​​ការវិភាគ​រ៉ូម​វ៉ាយហ្វាយ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"បិទកម្រិតសំឡេងលឺខ្លាំង"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"កំណែប្ល៊ូធូស AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ជ្រើសរើសកំណែប្ល៊ូធូស AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"កូឌិក​សំឡេង​ប៊្លូធូស"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ជ្រើសរើស​កូឌិក​សំឡេង​ប៊្លូធូស"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"អត្រា​គំរូ​សំឡេង​ប៊្លូធូស"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"កំពុង​ចាក់៖ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញ​ជម្រើស​សម្រាប់​វិញ្ញាបនបត្រ​បង្ហាញ​ឥត​ខ្សែ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុវ៉ាយហ្វាយបង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើស​វ៉ាយហ្វាយ"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"នៅពេលដែលបើក នោះ Wi‑Fi នឹងធ្វើការប្រគល់ការតភ្ជាប់ទិន្នន័យយ៉ាងគំហុកទៅបណ្តាញទូរសព្ទចល័ត នៅពេលរលកសញ្ញា Wi‑Fi ចុះខ្សោយ។"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"អនុញ្ញាត/មិន​អនុញ្ញាត​ការ​វិភាគ​រ៉ូម​​វ៉ាយហ្វាយ​ផ្អែក​លើ​​​ចំនួន​ការ​បង្ហាញ​ចរាចរណ៍​ទិន្នន័យ​​នៅ​ចំណុច​ប្រទាក់"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ទំហំ buffer របស់ Logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ជ្រើស​ទំហំ Logger per log buffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"នៅសល់ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញ"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញដោយប្រើឆ្នាំងសាក"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញដោយប្រើ USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញដោយឥតប្រើខ្សែ"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"មិន​ស្គាល់"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូល​ថ្ម"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិន​បញ្ចូលថ្ម"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"បានបើកដំណើរការដោយអ្នកគ្រប់គ្រង"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រង"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ទំព័រដើមនៃការកំណត់"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index c94dc235940b..2936bf084298 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRM ವಿಷಯಗಳಿಗೆ ಮಾತ್ರ HDCP ಪರೀಕ್ಷಿಸುವಿಕೆಯನ್ನು ಬಳಸು"</item>
<item msgid="45075631231212732">"HDCP ಪರಿಶೀಲನೆಯನ್ನು ಯಾವಾಗಲೂ ಬಳಸು"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ಡಿಫಾಲ್ಟ್)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"ಮೊನೊ"</item>
<item msgid="8883739882299884241">"ಸ್ಟೀರಿಯೊ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ಆಡಿಯೋ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ (990kbps/909kbps) ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item>
- <item msgid="2921767058740704969">"ಸಂತುಲಿತ ಆಡಿಯೊ ಮತ್ತು ಸಂಪರ್ಕದ ಗುಣಮಟ್ಟ (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"ಸಂಪರ್ಕದ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ (330kbps/303kbps) ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ಆಡಿಯೊ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ ಆಪ್ಟಿಮೈಸ್‌ ಮಾಡಲಾಗಿದೆ"</item>
- <item msgid="4327143584633311908">"ಸಂತುಲಿತ ಆಡಿಯೊ ಮತ್ತು ಸಂಪರ್ಕದ ಗುಣಮಟ್ಟ"</item>
- <item msgid="4681409244565426925">"ಸಂಪರ್ಕ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ಆಫ್"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 776c658c3b81..34d426c295ff 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವಿಲ್ಲ"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ರಿಂದ ಉಳಿಸಲಾಗಿದೆ"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"ಅತ್ಯಂತ ತ್ವರಿತ"</item>
<item msgid="9085102246155045744">"ಅತಿ ಕ್ಷಿಪ್ರ"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ವೈಯಕ್ತಿಕ"</string>
<string name="category_work" msgid="8699184680584175622">"ಕೆಲಸದ ಸ್ಥಳ"</string>
<string name="development_settings_title" msgid="215179176067683667">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ನೆಟ್‌ವರ್ಕಿಂಗ್"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ವೈರ್‌ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ವೈ-ಫೈನಿಂದ ಮೊಬೈಲ್‌ಗೆ ಆಕ್ರಮಣಕಾರಿ ಹಸ್ತಾಂತರ"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ವೈ-ಫೈ ರೋಮ್ ಸ್ಕ್ಯಾನ್‌ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿ"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಕೋಡೆಕ್"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೊ ಕೋಡೆಕ್ ಆಯ್ಕೆ ಮಾಡಿ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಮಾದರಿ ದರ"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ಸ್ಟ್ರೀಮಿಂಗ್: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್‌ಲೆಸ್‌‌‌ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ಇದು ಸಕ್ರಿಯಗೊಂಡರೆ, ವೈ-ಫೈ ಸಿಗ್ನಲ್ ದುರ್ಬಲವಾಗಿದ್ದಾಗ, ಮೊಬೈಲ್‌ಗೆ ಡೇಟಾ ಸಂಪರ್ಕವನ್ನು ಹಸ್ತಾಂತರಿಸುವಲ್ಲಿ ವೈ-ಫೈ ಹೆಚ್ಚು ಆಕ್ರಮಣಕಾರಿಯಾಗಿರುತ್ತದೆ"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ಇಂಟರ್‌ಫೇಸ್‌ನಲ್ಲಿ ಲಭ್ಯವಿರುವ ಡೇಟಾ ಟ್ರಾಫಿಕ್ ಆಧಾರದ ಮೇಲೆ Wi‑Fi ರೋಮ್ ಸ್ಕ್ಯಾನ್‌ಗಳನ್ನು ಅನುಮತಿಸಿ/ನಿರಾಕರಿಸಿ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ಲಾಗರ್ ಬಫರ್ ಗಾತ್ರಗಳು"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ಪ್ರತಿ ಲಾಗ್ ಬಫರ್‌ಗೆ ಲಾಗರ್ ಗಾತ್ರಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸುಮಾರು <xliff:g id="TIME">%2$s</xliff:g> ಬಾಕಿಯಿದೆ"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC ಮೂಲಕ ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ಮೂಲಕ ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - ವಯರ್‌ಲೆಸ್ ಮೂಲಕ ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ಅಪರಿಚಿತ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"ನಿರ್ವಾಹಕರಿಂದ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"ನಿರ್ವಾಹಕರಿಂದ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಮುಖಪುಟ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 8248fdb4d01b..62c018323a73 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRM 콘텐츠에 대해서만 HDCP 확인 사용"</item>
<item msgid="45075631231212732">"항상 HDCP 확인 사용"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4(기본)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"시스템 설정 사용(기본)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"모노"</item>
<item msgid="8883739882299884241">"스테레오"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"오디오 품질(990kbps/909kbps)에 최적화됨"</item>
- <item msgid="2921767058740704969">"오디오 및 연결 품질의 균형 유지(660Kbps/606Kbps)"</item>
- <item msgid="8860982705384396512">"연결 품질(330kbps/303kbps)에 최적화됨"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"오디오 품질에 최적화됨"</item>
- <item msgid="4327143584633311908">"오디오 및 연결 품질의 균형 유지"</item>
- <item msgid="4681409244565426925">"연결 품질에 최적화됨"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"사용 안함"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 735bb2210129..326d1d887a5d 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"자동으로 연결되지 않습니다."</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"인터넷에 연결되어 있지 않습니다."</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 저장됨"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s을(를) 통해 자동으로 연결됨"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s을(를) 통해 연결됨"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"매우 빠르게"</item>
<item msgid="9085102246155045744">"가장 빠르게"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"프로필 선택"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"개인"</string>
<string name="category_work" msgid="8699184680584175622">"직장"</string>
<string name="development_settings_title" msgid="215179176067683667">"개발자 옵션"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"네트워크"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"무선 디스플레이 인증서"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi 상세 로깅 사용"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"적극적인 Wi-Fi-모바일 핸드오버"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi 로밍 스캔 항상 허용"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"절대 볼륨 사용 안함"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"블루투스 AVRCP 버전"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"블루투스 AVRCP 버전 선택"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"블루투스 오디오 코덱"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"블루투스 오디오 코덱 선택"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"블루투스 오디오 샘플링 비율"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"스트리밍: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시합니다."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"사용 설정하면 Wi-Fi 신호가 약할 때 데이터 연결을 Wi-Fi에서 모바일 네트워크로 더욱 적극적으로 핸드오버합니다."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"인터페이스에 표시되는 데이터 트래픽의 양을 기반으로 Wi-Fi 로밍 스캔을 허용하거나 허용하지 않습니다."</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"로거 버퍼 크기"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"로그 버퍼당 로거 크기 선택"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음(AC 전원)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음(USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음(무선)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"알 수 없음"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"관리자가 제어"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"관리자가 사용 설정함"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"관리자가 사용 중지함"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"설정 홈"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 9cb2b172b54c..1d1480e34374 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP текшерүү DRM мазмунуна гана колдонулсун"</item>
<item msgid="45075631231212732">"Ар дайым HDCP текшерүү колдонулсун"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Демейки)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Тутум тандаганды колдонуу (демейки)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Аудионун сапатын оптималдаштыруу (990кб/сек./909кб/сек.)"</item>
- <item msgid="2921767058740704969">"Теңделген аудио жана туташуу сапаты (660кб/сек./606кб/сек.)"</item>
- <item msgid="8860982705384396512">"Туташуунун сапатын оптималдаштыруу (330кб/сек./303кб/сек.)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Аудионун сапатын оптималдаштыруу"</item>
- <item msgid="4327143584633311908">"Теңделген аудио жана туташуу сапаты"</item>
- <item msgid="4681409244565426925">"Туташуунун сапатын оптималдаштыруу"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Өчүк"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index d5716ba8c6cf..b5a8cf327bc3 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматтык түрдө туташпайт"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Интернетке туташпай турат"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s аркылуу автоматтык түрдө туташты"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Өтө тез"</item>
<item msgid="9085102246155045744">"Эң ылдам"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Профиль тандоо"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Жеке"</string>
<string name="category_work" msgid="8699184680584175622">"Жумуш"</string>
<string name="development_settings_title" msgid="215179176067683667">"Иштеп чыгуучунун параметрлери"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Тармактык байланыштарды кеңейтүү"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Зымсыз дисплейди аныктоо"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дайын-даректүү протоколун иштетүү"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi начар болсо, мобилдик Инт-ке өтсүн"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi Роуминг Скандоо мүмкүнчүлүгүнө ар дайым уруксат берилсин"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик дайындар ар дайым иштетилсин"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үндүн абсолюттук деңгээли өчүрүлсүн"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP версиясы"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP версиясын тандоо"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудио кодек"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth аудио кодегин тандаңыз"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth аудио үлгүсүнүн ылдамдыгы"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляция: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Зымсыз дисплейди сертификатто мүмкүнчүлүктөрүн көргөзүү"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi Кармагычта Wi‑Fi протокол деңгээлин жогорулатуу жана ар бир SSID RSSI үчүн көрсөтүү."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Иштетилсе, Wi-Fi байланышы үзүл-кесил болуп жатканда, Wi-Fi тармагы туташууну мобилдик Интернетке өжөрлүк менен өткөрүп берет"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Интерфейстеги дайындар трафигинин көлөмүнө жараша Wi-Fi Роуминг скандоо мүмкүнчүлүгүн иштетүү/өчүрүү"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Каттагыч буферлеринин өлчөмдөрү"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Каттоо буфери үчүн Каттагычтын көлөмүн тандаңыз"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Болжол менен <xliff:g id="TIME">%1$s</xliff:g> калды"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> калды"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – кубаттагычтан <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – USB аркылуу <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – зымсыз <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Белгисиз"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Администратор тарабынан көзөмөлдөнөт"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Администратор иштетип койгон"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Администратор өчүрүп койгон"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Жөндөөлөрдүн башкы бети"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 48bef580cd69..119779c4e615 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"ໃຊ້ການກວດສອບ HDCP ສຳລັບເນື້ອຫາ DRM ເທົ່ານັ້ນ"</item>
<item msgid="45075631231212732">"ໃຊ້ການກວດສອບ HDCP ສະເໝີ"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Use System Selection (Default)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"ໂທນດຽວ"</item>
<item msgid="8883739882299884241">"ສະເຕຣິໂອ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ປັບແຕ່ງສຳລັບຄຸນນະພາບສຽງ (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"ປັບແຕ່ງສຳລັບຄຸນນະພາບການເຊື່ອມຕໍ່ (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ປັບແຕ່ງສຳລັບຄຸນນະພາບສຽງ"</item>
- <item msgid="4327143584633311908">"Balanced Audio And Connection Quality"</item>
- <item msgid="4681409244565426925">"ປັບແຕ່ງສຳລັບຄຸນນະພາບການເຊື່ອມຕໍ່"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ປິດ"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 3dee662c4fc1..1972dc70a741 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ຈະບໍ່ເຊື່ອມຕໍ່ອັດຕະໂນມັດ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
<string name="saved_network" msgid="4352716707126620811">"ບັນທຶກ​​​ໂດຍ <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"​ເຊື່ອມຕໍ່​ຜ່ານ %1$s ​ແລ້ວ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"ມີ​ໃຫ້​ຜ່ານ %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"ໄວສຸດໆ"</item>
<item msgid="9085102246155045744">"ໄວທີ່ສຸດ"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"ເລືອກ​ໂປ​ຣ​ໄຟ​ລ໌"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"​ສ່ວນ​ໂຕ"</string>
<string name="category_work" msgid="8699184680584175622">"​ບ່ອນ​ເຮັດ​ວຽກ"</string>
<string name="development_settings_title" msgid="215179176067683667">"ໂຕເລືອກນັກພັດທະນາ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ການ​ສ້າງເຄືອຂ່າຍ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ສະແດງການຮັບຮອງຂອງລະບົບໄຮ້ສາຍ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"​ເປີດ​ນຳ​ໃຊ້ການ​ເກັບ​ປະ​ຫວັດ​ Verbose Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ອະ​ນຸ​ຍາດ​ການ​ສະ​ແກນ​ການ​ໂຣມ Wi‑Fi ​ສະ​ເໝີ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ປິດໃຊ້ລະດັບສຽງສົມບູນ"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມ​ລະ​ດັບ​ການ​ເກັບ​ປະ​ຫວັດ Wi‑Fi, ສະ​ແດງ​ຕໍ່ SSID RSSI ​ໃນ​ Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ເມື່ອ​ເປີດ​ນຳ​ໃຊ້​ແລ້ວ, ເຄືອ​ຂ່າຍ Wi-Fi ຈະ​ຖືກ​ປ່ຽນ​ໄປ​ໃຊ້​ເຄືອ​ຂ່າຍ​ໂທ​ລະ​ສັບ​ແທນ​ຫາກ​ສັນ​ຍານ Wi-Fi ອ່ອນ"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"​ອະ​ນຸ​ຍາດ/ບໍ່​ອະ​ນຸ​ຍາດການ​ສະ​ແກນ​ການ​ໂຣມ Wi-Fi ອີງ​ຕາມ​ຈຳ​ນວນ​ຂໍ້​ມູນທີ່​ເກີດ​ຂຶ້ນ​ໃນ​ລະ​ດັບ​ສ່ວນ​ຕິດ​ຕໍ່"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ຂະ​ໜາດ​​ບັບ​ເຟີໂຕ​ລັອກ"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ເລືອກ​ຂະ​ໜາດ​ລັອກ​ຕໍ່​ບັບ​ເຟີ"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ຍັງເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged on AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged over USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged from wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ບໍ່ຮູ້ຈັກ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"ຖືກເປີດໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"ຖືກປິດໄວ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ໜ້າທຳອິດຂອງການຕັ້ງຄ່າ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 25891742ac04..2c4c3215fc3c 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Taikyti HDCP tikrinimą tik DRM turiniui"</item>
<item msgid="45075631231212732">"Visada naudoti HDCP tikrinimą"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (numatytoji)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Naudoti sistemos pasirink. (numatytasis)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Monofoninis garsas"</item>
<item msgid="8883739882299884241">"Stereofoninis garsas"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizuota garso kokybė (990 Kb/s; 909 Kb/s)"</item>
- <item msgid="2921767058740704969">"Subalansuotą garso ir ryšio kokybė (660 kbps / 606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimizuota ryšio kokybė (330 Kb/s; 303 Kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizuota garso kokybė"</item>
- <item msgid="4327143584633311908">"Subalansuota garso ir ryšio kokybė"</item>
- <item msgid="4681409244565426925">"Optimizuota ryšio kokybė"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Išjungta"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 9d98e09c32e6..39c8c5ed0042 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nebus automatiškai prisijungiama"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nėra interneto ryšio"</string>
<string name="saved_network" msgid="4352716707126620811">"Išsaugojo <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiškai prisijungta naudojant „%1$s“"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Prisijungta naudojant „%1$s“"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Labai spartus"</item>
<item msgid="9085102246155045744">"Greičiausias"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profilio pasirinkimas"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Asmeninės"</string>
<string name="category_work" msgid="8699184680584175622">"Darbo"</string>
<string name="development_settings_title" msgid="215179176067683667">"Kūrėjo parinktys"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Tinklai"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Belaidžio rodymo sertifikavimas"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Įgal. „Wi‑Fi“ daugiaž. įraš. į žurnalą"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. „Wi‑Fi“ perd. į mob. r. tinklą"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Visada leisti „Wi-Fi“ tarptiklinio ryšio nuskaitymą"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Išjungti didžiausią garsą"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"„Bluetooth“ AVRCP versija"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pasirinkite „Bluetooth“ AVRCP versiją"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"„Bluetooth“ garso kodekas"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Pasirinkite „Bluetooth“ garso kodeką"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"„Bluetooth“ garso pavyzdžio dažnis"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Srautinis perdavimas: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Jei ši parinktis įgalinta, „Wi‑Fi“ agresyviau perduos duomenų ryšiu į mobiliojo ryšio tinklą, kai „Wi‑Fi“ signalas silpnas"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Leisti / neleisti „Wi‑Fi“ tarptinklinio ryšio nuskaitymo, atsižvelgiant į sąsajos duomenų srauto kiekį"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Registruotuvo buferio dydžiai"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Pasir. registr. dydž. žurn. bufer."</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo (kint. srovė)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo (per USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo (belaidis įkr.)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nežinomas"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Valdo administratorius"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Įgalino administratorius"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Išjungė administratorius"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Pagrindinis Nustatymų ekranas"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 0ae31f526d9d..664b4cf94b9a 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Izmantot HDCP pārbaudi tikai DRM saturam"</item>
<item msgid="45075631231212732">"Vienmēr izmantot HDCP pārbaudi"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (noklusējuma)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Sistēmas atlases izmantošana (nokl.)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Audio kvalitātes optimizēšana (990 Kb/s/909 Kb/s)"</item>
- <item msgid="2921767058740704969">"Samērīga audio un savienojuma kvalitāte (660 Kb/s/606 Kb/s)"</item>
- <item msgid="8860982705384396512">"Savienojuma kvalitātes optimizēšana (330 Kb/s/303 Kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Audio kvalitātes optimizēšana"</item>
- <item msgid="4327143584633311908">"Samērīga audio un savienojuma kvalitāte"</item>
- <item msgid="4681409244565426925">"Savienojuma kvalitātes optimizēšana"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Izslēgts"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index e09da0ea462c..df6b0809092e 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Savienojums netiks izveidots automātiski"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nav piekļuves internetam"</string>
<string name="saved_network" msgid="4352716707126620811">"Saglabāja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automātiski savienots, izmantojot %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Savienots, izmantojot %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Ļoti raiti"</item>
<item msgid="9085102246155045744">"Visātrāk"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profila izvēlēšanās"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Privāts"</string>
<string name="category_work" msgid="8699184680584175622">"Darba"</string>
<string name="development_settings_title" msgid="215179176067683667">"Izstrādātāju opcijas"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Tīklošana"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Bezvadu attēlošanas sertifikācija"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Iespējot Wi‑Fi detalizēto reģistrēšanu"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresīva pāreja no Wi‑Fi uz mobilo tīklu"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vienmēr atļaut Wi‑Fi meklēšanu"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Atspējot absolūto skaļumu"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versija"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Atlasiet Bluetooth AVRCP versiju"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodeks"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Atlasīt Bluetooth audio kodeku"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth audio iztveršanas ātrums"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Straumēšana: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ja opcija ir iespējota un Wi‑Fi signāls ir vājš, datu savienojuma pāreja no Wi-Fi uz mobilo tīklu tiks veikta agresīvāk."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Atļaujiet/neatļaujiet Wi‑Fi meklēšanu, pamatojoties uz saskarnē saņemto datplūsmas apjomu."</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Reģistrētāja buferu lielumi"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Atlasīt reģistrētāja bufera liel."</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - vēl apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — atlicis: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts kontaktligzdā"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts (USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts (bezvadu)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolē administrators"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Iespējojis administrators"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Atspējojis administrators"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Iestatījumu sākumekrāns"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 90a0d7242429..7a0c04783117 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Користи ХДЦП проверка само за ДРМ содржина"</item>
<item msgid="45075631231212732">"Секогаш користи ХДЦП проверка"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Стандардно)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Користи избор на системот (стандардно)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Оптимизирано за квалитет на аудиото (990 кб/с - 909 кб/с)"</item>
- <item msgid="2921767058740704969">"Балансиран квалитет на звукот и врската (660 kb/s/606 kb/s)"</item>
- <item msgid="8860982705384396512">"Оптимизирано за квалитет на врската (330 кб/с - 303 кб/с)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Оптимизирано за квалитет на аудиото"</item>
- <item msgid="4327143584633311908">"Балансиран квалитет на звукот и врската"</item>
- <item msgid="4681409244565426925">"Оптимизирано за квалитет на врската"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Исклучено"</item>
<item msgid="1593289376502312923">"64.000"</item>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 15c314b015a2..34e57184926c 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не може да се поврзе автоматски"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Нема пристап до Интернет"</string>
<string name="saved_network" msgid="4352716707126620811">"Зачувано од <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматски поврзано преку %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Поврзано преку %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Многу рапидно"</item>
<item msgid="9085102246155045744">"Најбрзо"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Изберете профил"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Лични"</string>
<string name="category_work" msgid="8699184680584175622">"Работа"</string>
<string name="development_settings_title" msgid="215179176067683667">"Програмерски опции"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Вмрежување"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Приказ на сертификација на безжична мрежа"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Овозможи преопширно пријавување Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресивно предавање од Wi‑Fi на мобилен"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Секогаш дозволувај Wi‑Fi скенирање во роаминг"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Оневозможете апсолутна јачина на звук"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Изберете верзија Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодек за аудио преку Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Изберете кодек за аудио преку Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Стапка на семпл преку Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Емитување: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Покажи ги опциите за безжичен приказ на сертификат"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Кога е овозможено, Wi-Fi ќе биде поагресивна при предавање на интернет-врската на мобилната мрежа при слаб сигнал на Wi-Fi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дозволи/Забрани Wi‑Fi скенирање во роаминг според количината на постоечкиот податочен сообраќај на интерфејсот."</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Величини на меѓумеморија на забележувач"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Величина/меѓумеморија на дневник"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно преку AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно преку USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно преку Wi-Fi"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Полна"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролирано од администраторот"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Овозможено од администраторот"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Оневозможено од администраторот"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Почетна страница за поставки"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 13d65e7bb37b..fe28f588965d 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRM ഉള്ളടക്കത്തിനുമാത്രമായി HDCP പരിശോധന ഉപയോഗിക്കുക"</item>
<item msgid="45075631231212732">"എല്ലായ്‌പ്പോഴും HDCP പരിശോധന ഉപയോഗിക്കുക"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ഡിഫോൾട്ട്)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"മോണോ"</item>
<item msgid="8883739882299884241">"സ്റ്റീരിയോ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ശബ്‌ദനിലവാരമുയർത്താൻ ഒപ്‌റ്റിമൈസ് ചെയ്‌തു (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"സന്തുലിതമായ ‌ഓഡിയോ/കണക്ഷൻ നിലവാരം (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"കണക്ഷൻ നിലവാരമുയർത്താൻ ഒപ്‌റ്റിമൈസ് ചെയ്‌തു (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ശബ്‌ദനിലവാരമുയർത്താൻ ഒപ്‌റ്റിമൈസ് ചെയ്‌തു"</item>
- <item msgid="4327143584633311908">"സന്തുലിതമായ ‌ഓഡിയോ/കണക്ഷൻ നിലവാരം"</item>
- <item msgid="4681409244565426925">"കണക്ഷൻ നിലവാരമുയർത്താൻ ഒപ്‌റ്റിമൈസ് ചെയ്‌തു"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ഓഫ്"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 6501fba88ed1..420502b49b5f 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"സ്വയമേവ കണക്‌റ്റുചെയ്യില്ല"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ഇന്റർനെറ്റ് ആക്‌സസ്സ് ഇല്ല"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> സംരക്ഷിച്ചത്"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s വഴി സ്വയമേവ ബന്ധിപ്പിച്ചു"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"വളരെ ശീഘ്രം"</item>
<item msgid="9085102246155045744">"ഏറ്റവും വേഗത്തിൽ"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"പ്രൊഫൈൽ തിരഞ്ഞെടുക്കുക"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"വ്യക്തിഗതം"</string>
<string name="category_work" msgid="8699184680584175622">"ഔദ്യോഗികം"</string>
<string name="development_settings_title" msgid="215179176067683667">"ഡെവലപ്പർ ഓ‌പ്ഷനുകൾ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"നെറ്റ്‍വര്‍ക്കിംഗ്"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷൻ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"വൈഫൈ വെർബോസ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"മൊബൈൽ ഹാൻഡ്ഓവറിലേക്ക് വൈഫൈ സക്രിയമാക്കുക"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"എപ്പോഴും വൈഫൈ റോം സ്‌‌കാൻ അനുവദിക്കൂ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്‌പ്പോഴും സജീവം"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"അബ്‌സൊല്യൂട്ട് വോളിയം പ്രവർത്തനരഹിതമാക്കുക"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP പതിപ്പ്"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP പതിപ്പ് തിരഞ്ഞെടുക്കുക"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth ഓഡിയോ കോഡെക്"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth ഓഡിയോ കോഡെക് തിരഞ്ഞെടുക്കുക"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth ഓഡിയോ സാമ്പിൾ നിരക്ക്"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"സ്ട്രീമിംഗ്: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്‌ഷനുകൾ ദൃശ്യമാക്കുക"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"പ്രവർത്തനക്ഷമമായിരിക്കുമ്പോൾ, വൈഫൈ സിഗ്‌നൽ കുറവായിരിക്കുന്ന സമയത്ത് മൊബൈലിലേക്ക് ഡാറ്റ കണക്ഷൻ വഴി കൈമാറുന്നതിൽ വൈഫൈ കൂടുതൽ സക്രിയമായിരിക്കും"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ഇന്റർഫേസിലെ ഡാറ്റ ട്രാഫിക്ക് സാന്നിദ്ധ്യത്തിന്റെ കണക്ക് അടിസ്ഥാനമാക്കി വൈഫൈ റോം സ്‌കാനുകൾ അനുവദിക്കുക/അനുവദിക്കാതിരിക്കുക"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ലോഗർ ബഫർ വലുപ്പം"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ഓരോ ലോഗ് ബഫറിനും വലുപ്പം തിരഞ്ഞെടുക്കൂ"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏതാണ്ട് <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - വയർലെസ് വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"അഡ്‌മിൻ നിയന്ത്രിക്കുന്നത്"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"അഡ്‌മിനിസ്ട്രേറ്റർ പ്രവർത്തനക്ഷമമാക്കി"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"അഡ്‌മിനിസ്ട്രേറ്റർ പ്രവർത്തനരഹിതമാക്കി"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ക്രമീകരണ ഹോം"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index e252d2f6afe3..af033d228143 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP шалгахыг зөвхөн DRM контентэд ашиглах"</item>
<item msgid="45075631231212732">"Байнга HDCP шалгахыг ашиглах"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Өгөгдмөл)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Аудио чанарт тааруулсан (990кб/цаг/909кб/цаг)"</item>
- <item msgid="2921767058740704969">"Аудио, холболтын чанарыг тэнцүүлсэн (660кб/цаг/606кб/цаг)"</item>
- <item msgid="8860982705384396512">"Холболтын чанарт тааруулсан (330кб/цаг/303кб/цаг)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Аудио чанарт тааруулсан"</item>
- <item msgid="4327143584633311908">"Аудио, холболтын чанарыг тэнцүүлсэн"</item>
- <item msgid="4681409244565426925">"Холболтын чанарт тааруулсан"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Идэвхгүй"</item>
<item msgid="1593289376502312923">"64000"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index ce6a637122ce..6740d2751954 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Автоматаар холбогдохгүй"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Интернэт холболт алга"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> хадгалсан"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s-р автоматаар холбогдсон"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-р холбогдсон"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Маш түргэн"</item>
<item msgid="9085102246155045744">"Хамгийн хурдан"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Профайлаа сонгоно уу"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Хувийн"</string>
<string name="category_work" msgid="8699184680584175622">"Ажил"</string>
<string name="development_settings_title" msgid="215179176067683667">"Хөгжүүлэгчийн тохиргоо"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Сүлжээ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Утасгүй дэлгэцийн сертификат"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Verbose лог-г идэвхжүүлэх"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Идэвхтэй Wi‑Fi-с мобайл сүлжээнд"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Роум сканыг байнга зөвшөөрөх"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үнэмлэхүй дууны түвшинг идэвхгүй болгох"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP хувилбар"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP хувилбарыг сонгох"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудио кодлогч"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth аудио кодлогч сонгох"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth аудио жишээний үнэлгээ"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Дамжуулж байна: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Идэвхжүүлсэн үед Wi‑Fi холболт сул байх үед дата холболтыг мобайлд шилжүүлэхэд илүү идэвхтэй байх болно"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Интерфэйс дээрх дата трафикын хэмжээнээс хамааран Wi‑Fi Роум Скан-г зөвшөөрөх/үл зөвшөөрөх"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Логгерын буферын хэмжээ"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Лог буфер бүрт ногдох логгерын хэмжээг сонгоно уу"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>-с <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"AC-р бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"USB-р бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"Wi-Fi-р бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Тодорхойгүй"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Админ удирдсан"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Админ идэвхтэй болгосон"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Админ идэвхгүй болгосон"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Тохиргооны нүүр хуудас"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 218833df29f5..17a1b11b4a1f 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"केवळ DRM सामग्रीसाठी HDCP तपासणी वापरा"</item>
<item msgid="45075631231212732">"नेहमी HDCP तपासणी वापरा"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (डीफॉल्ट)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"मोनो"</item>
<item msgid="8883739882299884241">"स्टिरिओ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ऑडिओ गुणवत्ता (990kbps/909kbps) साठी ऑप्टिमाइझ केली"</item>
- <item msgid="2921767058740704969">"संतुलित ऑडिओ आणि कनेक्शन गुणवत्ता (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"कनेक्शन गुणवत्ता (330kbps/303kbps) साठी ऑप्टिमाइझ केली"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ऑडिओ गुणवत्तेसाठी ऑप्टिमाइझ केले"</item>
- <item msgid="4327143584633311908">"संतुलित ऑडिओ आणि कनेक्शन गुणवत्ता"</item>
- <item msgid="4681409244565426925">"कनेक्शन गुणवत्तेसाठी ऑप्टिमाइझ केले"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"बंद"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a0879e1216b1..e1938cde5b73 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वयंचलितपणे कनेक्ट करणार नाही"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"इंटरनेट प्रवेश नाही"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे जतन केले"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s द्वारे कनेक्‍ट केले"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्‍ध"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"अतिशीघ्र"</item>
<item msgid="9085102246155045744">"जलद"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"प्रोफाईल निवडा"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"वैयक्तिक"</string>
<string name="category_work" msgid="8699184680584175622">"कार्य"</string>
<string name="development_settings_title" msgid="215179176067683667">"विकासक पर्याय"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस प्रदर्शन प्रमाणीकरण"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय शब्दपाल्हाळ लॉगिंग सक्षम करा"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"मोबाइलकडे सोपवण्यासाठी आक्रमक वाय-फाय"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"वाय-फाय रोम स्‍कॅनला नेहमी अनुमती द्या"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"संपूर्ण आवाज अक्षम करा"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटुथ AVRCP आवृत्ती"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लूटुथ AVRCP आवृत्ती निवडा"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ब्लूटूथ ऑडिओ कोडेक"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ब्लूटुथ ऑडिओ कोडेक निवडा"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ब्लूटूथ ऑडिओ नमुना दर"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"धारावाहिक: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस प्रदर्शन प्रमाणिकरणासाठी पर्याय दर्शवा"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्‍तर वाढवा, वाय-फाय निवडकामध्‍ये प्रति SSID RSSI दर्शवा"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम केले असताना, वाय-फाय सिग्‍नल कमी असताना, मोबाइलकडे डेटा कनेक्‍शन सोपवण्यासाठी वाय-फाय अधिक आक्रमक असेल."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"वाय-फाय रोम स्‍कॅनला इंटरफेसवर उपस्‍थित असलेल्‍या रहदारी डेटाच्या प्रमाणावर आधारित अनुमती द्या/अनुमती देऊ नका"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफर आकार"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"प्रति लॉग बफर लॉगर आकार निवडा"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC वर पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB वर पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - वायरलेसवरून पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकाने नियंत्रित केलेले"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"प्रशासकाने सक्षम केलेले"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"प्रशासकाने अक्षम केलेले"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"सेटिंग्ज मुख्यपृष्ठ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index 6629591b1331..a9d15613b0ca 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Gunakan penyemakan HDCP untuk kandungan DRM sahaja"</item>
<item msgid="45075631231212732">"Sentiasa gunakan penyemakan HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Lalai)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Lalai)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Dioptimumkan untuk Kualiti Audio (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Audio Seimbang dan Kualiti Sambungan (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Dioptimumkan untuk Kualiti Sambungan (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Dioptimumkan untuk Kualiti Audio"</item>
- <item msgid="4327143584633311908">"Audio Seimbang dan Kualiti Sambungan"</item>
- <item msgid="4681409244565426925">"Dioptimumkan untuk Kualiti Sambungan"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Mati"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 3ba846e0e62e..2433d792cacc 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Tidak akan menyambung secara automatik"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Tiada akses Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Diselamatkan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Disambungkan secara automatik melalui %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Disambungkan melalui %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Sangat pantas"</item>
<item msgid="9085102246155045744">"Paling laju"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Pilih Profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Peribadi"</string>
<string name="category_work" msgid="8699184680584175622">"Tempat Kerja"</string>
<string name="development_settings_title" msgid="215179176067683667">"Pilihan pembangun"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Perangkaian"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Pensijilan paparan wayarles"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Dayakan Pengelogan Berjela-jela Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Penyerahan Wi-Fi ke mudah alih agresif"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sentiasa benarkan Imbasan Perayauan Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Lumpuhkan kelantangan mutlak"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pilih Versi AVRCP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec Audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Pilih Codec Audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Kadar Sampel Audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Penstriman: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Apabila didayakan, Wi-Fi akan menjadi lebih agresif dalam menyerahkan sambungan data ke mudah alih, apabila isyarat Wi-Fi rendah"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Benarkan/Jangan benarkan Imbasan Perayauan Wi-Fi berdasarkan jumlah trafik data yang ada pada antara muka"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Saiz penimbal pengelog"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Pilih saiz Pengelog bagi setiap penimbal log"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh menggunakan AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh melalui USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh drp wayarles"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikawal oleh pentadbir"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Didayakan oleh pentadbir"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Dilumpuhkan oleh pentadbir"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Laman Utama Tetapan"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 22ac5aa12de1..22e91ac9ceb3 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRMအကြောင်းအရာအတွက် HDCPစစ်ဆေးခြင်းကိုသုံးမည်"</item>
<item msgid="45075631231212732">"HDCP checkingအားအမြဲသုံးပါ"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (မူလ)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"မိုနို"</item>
<item msgid="8883739882299884241">"စတီရီယို"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"အသံအရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည် (၉၉၀kbps/၉၀၉kbps)"</item>
- <item msgid="2921767058740704969">"အသံနှင့် ချိတ်ဆက်မှု အရည်အသွေးကို မျှတအောင် ချိန်ဆပေးသည် (၆၆၀kbps/၆၀၆kbps)"</item>
- <item msgid="8860982705384396512">"ချိတ်ဆက်မှု အရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည် (၃၃၀kbps/၃၀၃kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"အသံအရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည်"</item>
- <item msgid="4327143584633311908">"အသံနှင့် ချိတ်ဆက်မှု အရည်သွေးကို မျှတအောင် ချိန်ဆပေးသည်"</item>
- <item msgid="4681409244565426925">"ချိတ်ဆက်မှု အရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည်"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ပိတ်ပါ"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index f53a28d84a8e..998801c2c9fc 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"အလိုအလျောက်ချိတ်ဆက်မည်မဟုတ်ပါ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"အင်တာနက် ချိတ်ဆက်မှု မရှိပါ"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> မှသိမ်းဆည်းခဲ့သည်"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"အရမ်းသွက်"</item>
<item msgid="9085102246155045744">"အမြန်ဆုံး"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"ပရိုဖိုင်ရွေးရန်"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ကိုယ်ရေး"</string>
<string name="category_work" msgid="8699184680584175622">"အလုပ်အကိုင်"</string>
<string name="development_settings_title" msgid="215179176067683667">"ဆော့ဝဲလ်ရေးသူ၏ ရွေးချယ်မှုများ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ကွန်ရက်လုပ်ငန်း"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ကြိုးမဲ့ပြသမှု အသိအမှတ်ပြုလက်မှတ်"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Verbose မှတ်တမ်းတင်ခြင်းအား ဖွင့်မည်"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi မှ မိုဘိုင်းသို့ လွှဲပြောင်းရန်"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi ရွမ်းရှာဖွေမှုကို အမြဲတမ်း ခွင့်ပြုမည်"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ပကတိ အသံနှုန်း သတ်မှတ်ချက် ပိတ်ရန်"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ဘလူးတုသ် AVRCP ဗားရှင်း"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ဘလူးတုသ် AVRCP ဗားရှင်းကို ရွေးပါ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ဘလူးတုသ်အသံ ကိုးဒက်ခ်"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ဘလူးတုသ်အသံကိုးဒက်ခ်ကို ရွေးပါ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ဘလူးတုသ်အသံနမူနာနှုန်း"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"တိုက်ရိုက်လွှင့်နေသည်− <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ဖွင့်ထားပါက Wi‑Fi လွှင့်အား နည်းချိန်တွင် Wi‑Fi မှ မိုဘိုင်းသို့ ဒေတာချိတ်ဆက်မှုကို လွှဲပြောင်းရာ၌ ပိုမိုထိရောက်ပါသည်"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"မျက်နှာပြင်တွင် ဖော်ပြသည့် အချက်လက် အသွားအလာ ပမာဏပေါ်တွင် အခြေခံ၍ WIFI ရွမ်းရှာဖွေမှုအား ဖွင့်/ပိတ်မည်"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"လော့ဂါး ဘာဖား ဆိုက်များ"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"လော့ ဘာဖားတွက် လော့ဂါးဆိုက် ရွေး"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ခန့်မှန်းခြေ <xliff:g id="TIME">%1$s</xliff:g> ကျန်ပါသည်"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> − <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> − အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> − AC ဖြင့် အားအပြည့်သွင်းရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> − USB ဖြင့် အားအပြည့်သွင်းရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> − ဝါယာလက်စနစ်ဖြင့်အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"အကြောင်းအရာ မသိရှိ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"စီမံခန့်ခွဲသူမှ ဖွင့်ထားသည်"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"စီမံခန့်ခွဲသူမှ ပိတ်ထားသည်"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ဆက်တင် ပင်မစာမျက်နှာ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"၀%"</item>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 605a8ded550f..ba555bc85411 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Bruk HDCP-kontroll kun for DRM-innhold"</item>
<item msgid="45075631231212732">"Bruk alltid HDCP-kontroll"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Bruk systemvalg (standard)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimalisert for lydkvalitet (990 kbps / 909 kbps)"</item>
- <item msgid="2921767058740704969">"Balansert lyd- og tilkoblingskvalitet (660 kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Optimalisert for tilkoblingskvalitet (330 kbps / 303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimalisert for lydkvalitet"</item>
- <item msgid="4327143584633311908">"Balansert lyd- og tilkoblingskvalitet"</item>
- <item msgid="4681409244565426925">"Optimalisert for tilkoblingskvalitet"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Av"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index bcb30cda4635..1fdfe5d6d466 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Kobler ikke til automatisk"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ingen Internett-tilgang"</string>
<string name="saved_network" msgid="4352716707126620811">"Lagret av <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisk tilkoblet via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tilkoblet via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Veldig hurtig"</item>
<item msgid="9085102246155045744">"Raskest"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Velg profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personlig"</string>
<string name="category_work" msgid="8699184680584175622">"Jobb"</string>
<string name="development_settings_title" msgid="215179176067683667">"Utvikleralternativer"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Nettverk"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Trådløs skjermsertifisering"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiver detaljert Wi-Fi-loggføring"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv overføring fra Wi-Fi til mobil"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillat alltid skanning for Wi-Fi-roaming"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slå av funksjonen for absolutt volum"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-versjon"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Velg Bluetooth AVRCP-versjon"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodek for Bluetooth-lyd"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Velg kodek for Bluetooth-lyd"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Samplefrekvens for Bluetooth-lyd"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strømming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Hvis dette slås på, overfører Wi-Fi-nettverket datatilkoblingen til mobil mer aggressivt når Wi-Fi-signalet er svakt"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Tillat / ikke tillat skanning for Wi-Fi-roaming basert på mengden datatrafikk til stede i grensesnittet"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Bufferstørrelser for logg"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Velg loggstørrelse per loggbuffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet via strømuttak"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet via USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til full lading via trådløs lading"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ukjent"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrollert av administratoren"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Slått på av administratoren"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Avslått av administratoren"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Innstillinger for startsiden"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 7bf3b4f18f32..d3e0cd625a0c 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRM सामग्रीको लागि मात्र HDCP जाँचको प्रयोग गर्नुहोस्"</item>
<item msgid="45075631231212732">"सधैँ HDCP जाँच प्रयोग गर्नुहोस्"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP १.४ (पूर्वनिर्धारित)"</item>
+ <item msgid="2089555299377409443">"AVRCP १.५"</item>
+ <item msgid="2895327394279434278">"AVRCP १.६"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"मोनो"</item>
<item msgid="8883739882299884241">"स्टेरियो"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"अडियोको गुणस्तर सुधार्न अनुकूलन गरिएको (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"सन्तुलित अडियो र जडान गुणस्तर (६६०kbps/६०६kbps)"</item>
- <item msgid="8860982705384396512">"जडानको गुणस्तर सुधार्न अनुकूलन गरिएको (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"अडियोको गुणस्तर सुधार्न अनुकूलन गरिएको"</item>
- <item msgid="4327143584633311908">"सन्तुलित अडियो र जडान गुणस्तर"</item>
- <item msgid="4681409244565426925">"जडानको गुणस्तर सुधार्न अनुकूलन गरिएको"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"निष्क्रिय गर्नुहोस्"</item>
<item msgid="1593289376502312923">"६४के"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 7ccf28bd5ef2..e3dbd9d36593 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वतः जडान हुने छैन"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"इन्टरनेट माथिको पहुँच छैन"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा सुरक्षित गरियो"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s मार्फत् स्वतः जडान गरिएको"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s मार्फत जडित"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"धेरै तीव्र"</item>
<item msgid="9085102246155045744">"सबभन्दा छिटो"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"प्रोफाइल रोज्नुहोस्"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string>
<string name="category_work" msgid="8699184680584175622">"काम"</string>
<string name="development_settings_title" msgid="215179176067683667">"विकासकर्ताका विकल्पहरू"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किङ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ताररहित प्रदर्शन प्रमाणीकरण"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"आक्रामक ढंगले Wi‑Fi बाट मोबाइलमा हस्तान्तरण"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi घुम्ने स्क्यान गर्न सधैँ अनुमति दिनुहोस्"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"निरपेक्ष आवाज असक्षम गर्नुहोस्"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लुटुथको AVRCP संस्करण"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ब्लुटुथको AVRCP संस्करण चयन गर्नुहोस्"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ब्लुटुथ अडियोको कोडेक"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ब्लुटुथ अडियोको कोडेक चयन गर्नुहोस्‌"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ब्लुटुथ अडियोको नमूना दर"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"स्ट्रिमिङ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम गरिएको अवस्थामा, Wi-Fi सिग्नल न्यून हुँदा, Wi-Fi ले बढी आक्रामक ढंगले मोबाइलमा डेटा जडान हस्तान्तरण गर्नेछ"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Wi-Fi घुम्ने स्क्यान इन्टरफेसमा रहेको डेटा यातायातको मात्रामा आधारित अनुमति दिनुहोस्/नदिनुहोस्"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"लगर बफर आकारहरू"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"लग बफर प्रति लगर आकार चयन गर्नुहोस्"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी छ"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"बाँकी समय <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - करिब <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"बाँकी समय <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC मा पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB मार्फत पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - वायरलेसबाट पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकद्वारा नियन्त्रित"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"प्रशासकद्वारा सक्षम गरिएको छ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"प्रशासकद्वारा असक्षम गरिएको छ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"सेटिङहरूको गृहपृष्ठ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"०%"</item>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 7962e407e3a1..1147c89ffe9d 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP-controle alleen voor DRM-content gebruiken"</item>
<item msgid="45075631231212732">"HDCP-controle altijd gebruiken"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (standaard)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Systeemselectie gebruiken (standaard)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Geoptimaliseerd voor audiokwaliteit (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Gebalanceerde audio- en verbindingskwaliteit (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Geoptimaliseerd voor verbindingskwaliteit (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Geoptimaliseerd voor audiokwaliteit"</item>
- <item msgid="4327143584633311908">"Gebalanceerde audio- en verbindingskwaliteit"</item>
- <item msgid="4681409244565426925">"Geoptimaliseerd voor verbindingskwaliteit"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Uit"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index a41072d5f6a2..0c315b9c6ca9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Er wordt niet automatisch verbinding gemaakt"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Geen internettoegang"</string>
<string name="saved_network" msgid="4352716707126620811">"Opgeslagen door <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisch verbonden via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Verbonden via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Snelst"</item>
<item msgid="9085102246155045744">"Allerallersnelst"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profiel kiezen"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Persoonlijk"</string>
<string name="category_work" msgid="8699184680584175622">"Werk"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opties voor ontwikkelaars"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netwerken"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificering van draadloze weergave"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Uitgebreide wifi-logregistratie insch."</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agressieve handover van wifi naar mobiel"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Altijd roamingscans voor wifi toestaan"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Absoluut volume uitschakelen"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-AVRCP-versie"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth-AVRCP-versie selecteren"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth-audiocodec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth-audiocodec selecteren"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bemonsteringsfrequentie (sample rate) van Bluetooth-audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Indien ingeschakeld, is wifi agressiever bij het overgeven van de gegevensverbinding aan mobiel wanneer het wifi-signaal zwak is"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Roamingscans voor wifi (niet) toestaan op basis van de hoeveelheid dataverkeer die aanwezig is bij de interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger-buffergrootten"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Kies Logger-grootten per logbuffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ongeveer <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen via netvoeding"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen via USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen via draadloos"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ingesteld door beheerder"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Ingeschakeld door beheerder"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Uitgeschakeld door beheerder"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Homepage voor instellingen"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index cb91b57ae71f..7454776c4d36 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"ਕੇਵਲ DRM ਸਮੱਗਰੀ ਲਈ HDCP ਜਾਂਚ"</item>
<item msgid="45075631231212732">"ਹਮੇਸਾਂ HDCP ਜਾਂਚ ਵਰਤੋ"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"ਮੋਨੋ"</item>
<item msgid="8883739882299884241">"ਸਟੀਰੀਓ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ਔਡੀਓ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"ਸੰਤੁਲਿਤ ਔਡੀਓ ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ਔਡੀਓ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item>
- <item msgid="4327143584633311908">"ਸੰਤੁਲਿਤ ਔਡੀਓ ਅਤੇ ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ"</item>
- <item msgid="4681409244565426925">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ਬੰਦ"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index a179818e943d..d2876f297091 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ਵੱਲੋਂ ਸੁਰੱਖਿਅਤ ਕੀਤਾ"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"ਬਹੁਤ ਤੇਜ਼"</item>
<item msgid="9085102246155045744">"ਸਭ ਤੋਂ ਵੱਧ ਤੇਜ਼"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ਨਿੱਜੀ"</string>
<string name="category_work" msgid="8699184680584175622">"ਦਫ਼ਤਰ"</string>
<string name="development_settings_title" msgid="215179176067683667">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ਨੈਟਵਰਕਿੰਗ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ਵਰਬੋਸ ਲੌਗਿੰਗ ਸਮਰੱਥ ਬਣਾਓ"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ਆਕਰਮਣਸ਼ੀਲ Wi‑Fi ਤੋਂ ਮੋਬਾਈਲ ਹੈਂਡਓਵਰ"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ਹਮੇਸ਼ਾਂ Wi‑Fi Roam Scans ਦੀ ਆਗਿਆ ਦਿਓ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡੈਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ਪੂਰਨ ਵੌਲਿਊਮ ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ ਚੁਣੋ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕੋਡੇਕ ਚੁਣੋ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਨਮੂਨਾ ਦਰ"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ਸਟ੍ਰੀਮਿੰਗ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਦਿਖਾਓ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, Wi‑Fi Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ਜਦੋਂ ਯੋਗ ਬਣਾਇਆ ਹੋਵੇ, ਤਾਂ Wi‑Fi ਸਿਗਨਲ ਘੱਟ ਹੋਣ \'ਤੇ Wi‑Fi ਡੈਟਾ ਕਨੈਕਸ਼ਨ ਮੋਬਾਈਲ ਨੂੰ ਹੈਂਡ ਓਵਰ ਕਰਨ ਵਿੱਚ ਵੱਧ ਆਕਰਮਣਸ਼ੀਲ ਹੋਵੇਗਾ।"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ਇੰਟਰਫੇਸ ਤੇ ਮੌਜੂਦ ਡੈਟਾ ਟ੍ਰੈਫਿਕ ਦੀ ਮਾਤਰਾ ਦੇ ਆਧਾਰ ਤੇ Wi‑Fi ਰੋਮ ਸਕੈਨ ਦੀ ਆਗਿਆ ਦਿਓ/ਅਸਵੀਕਾਰ ਕਰੋ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫਰ ਆਕਾਰ"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ਪ੍ਰਤੀ ਲੌਗ ਬਫਰ ਲੌਗਰ ਆਕਾਰ ਚੁਣੋ"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"AC \'ਤੇ ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"USB \'ਤੇ ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"ਵਾਇਰਲੈੱਸ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜਿੰਗ"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਯੋਗ ਬਣਾਈ ਗਈ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ਸੈਟਿੰਗਾਂ ਮੁੱਖ ਪੰਨਾ"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 6a79cfe5738a..ca0a60db0315 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Użyj sprawdzania HDCP tylko w przypadku treści chronionych DRM"</item>
<item msgid="45075631231212732">"Zawsze używaj sprawdzania HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (domyślna)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Użyj wyboru systemu (domyślnie)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optymalizacja pod kątem jakości dźwięku (990 kb/s lub 909 kb/s)"</item>
- <item msgid="2921767058740704969">"Zrównoważona jakość dźwięku i połączenia (660 kb/s lub 606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optymalizacja pod kątem jakości połączenia (330 kb/s lub 303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optymalizacja pod kątem jakości dźwięku"</item>
- <item msgid="4327143584633311908">"Zrównoważona jakość dźwięku i połączenia"</item>
- <item msgid="4681409244565426925">"Optymalizacja pod kątem jakości połączenia"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Wył."</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 28a92dfc7ab4..019061edc0df 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nie można połączyć automatycznie"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Brak dostępu do internetu"</string>
<string name="saved_network" msgid="4352716707126620811">"Zapisane przez: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatycznie połączono przez: %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Połączono przez %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Bardzo szybko"</item>
<item msgid="9085102246155045744">"Najszybciej"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Wybierz profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Osobiste"</string>
<string name="category_work" msgid="8699184680584175622">"Praca"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opcje programistyczne"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Sieci"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wyświetlacz bezprzewodowy"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Szczegółowy dziennik Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Przełączaj z Wi-Fi na sieć komórkową"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Zawsze szukaj Wi-Fi w roamingu"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Wyłącz głośność bezwzględną"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Wersja AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Wybierz wersję AVRCP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodek dźwięku Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Wybierz kodek dźwięku Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Dźwięk Bluetooth – współczynnik próbkowania"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strumieniowe przesyłanie danych: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Po włączeniu połączenie danych będzie bardziej agresywnie przełączać się z Wi-Fi na sieć komórkową przy słabym sygnale Wi-Fi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Zezwalaj/nie zezwalaj na wyszukiwanie sieci Wi-Fi w roamingu w zależności od natężenia ruchu"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Rozmiary bufora Rejestratora"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Wybierz rozmiary Rejestratora/bufor dziennika"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Pozostało około <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostało <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – pozostało około <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania (ładowarka)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania (USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania (bezprzewod.)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nieznane"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolowane przez administratora"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Włączone przez administratora"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Wyłączone przez administratora"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ekran główny ustawień"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index 864eaaf4d768..7b17e6cc6d4b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Usar a verificação HDCP somente para conteúdo DRM"</item>
<item msgid="45075631231212732">"Sempre usar a verificação HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estéreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Otimizado para qualidade de áudio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Qualidade de áudio e de conexão balanceada (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Otimizado para qualidade de conexão (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Otimizado para qualidade de áudio"</item>
- <item msgid="4327143584633311908">"Qualidade de áudio e de conexão balanceada"</item>
- <item msgid="4681409244565426925">"Otimizado para qualidade de conexão"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Desativado"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 9b649c79cda5..1ca691f22706 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Muito rápida"</item>
<item msgid="9085102246155045744">"Super-rápida"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
<string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opções do desenvolvedor"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro extenso de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecionar versão do Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecionar codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de amostra do áudio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quando ativada, o Wi-Fi será mais agressivo em passar a conexão de dados para móvel, quando o sinal de Wi-Fi estiver fraco"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/proibir verificações de roaming de Wi-Fi com base no volume do tráfego de dados presente na interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Sel. tam. de logger/buffer de log"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa em CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa por USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa sem fio"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Ativada pelo administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Desativada pelo administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Página inicial das configurações"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index ff2fe91488b3..a5754804bf4a 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utilizar a verificação HDCP para conteúdo DRM apenas"</item>
<item msgid="45075631231212732">"Utilizar sempre a verificação HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (predefinição)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Utilizar seleção do sistema (predef.)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estéreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Otimizado para a qualidade do áudio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Qualidade de áudio e de ligação equilibrada (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Otimizado para a qualidade da ligação (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Otimizado para a qualidade do áudio"</item>
- <item msgid="4327143584633311908">"Qualidade de áudio e de ligação equilibradas"</item>
- <item msgid="4681409244565426925">"Otimizado para a qualidade da ligação"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Desativado"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 879788976213..bd148821d57a 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não é efetuada uma ligação automaticamente"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ligado automaticamente através de %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Ligado através de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Muito acelerada"</item>
<item msgid="9085102246155045744">"A mais rápida"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
<string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opções de programador"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de display sem fios"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar o registo verboso de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transm. agressiva de Wi‑Fi p/ rede móvel"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre a deteção de Wi-Fi em roaming"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão de Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecionar versão de Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecionar codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de amostragem de áudio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmissão em fluxo contínuo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Se estiver ativado, o Wi-Fi será mais agressivo ao transmitir a lig. de dados para a rede móvel quando o sinal Wi-Fi estiver fraco"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/impedir a deteção de Wi-Fi em roaming com base na quantidade de tráfego de dados presente na interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos da memória intermédia do registo"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Selec. tam. reg. p/ mem. int. reg."</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – falta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada em CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carreg. via USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carreg. s/ fios"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo administrador"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Ativado pelo administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Desativado pelo administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Página inicial de definições"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index 864eaaf4d768..7b17e6cc6d4b 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Usar a verificação HDCP somente para conteúdo DRM"</item>
<item msgid="45075631231212732">"Sempre usar a verificação HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Estéreo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Otimizado para qualidade de áudio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Qualidade de áudio e de conexão balanceada (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Otimizado para qualidade de conexão (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Otimizado para qualidade de áudio"</item>
- <item msgid="4327143584633311908">"Qualidade de áudio e de conexão balanceada"</item>
- <item msgid="4681409244565426925">"Otimizado para qualidade de conexão"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Desativado"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 9b649c79cda5..1ca691f22706 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Muito rápida"</item>
<item msgid="9085102246155045744">"Super-rápida"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
<string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opções do desenvolvedor"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro extenso de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selecionar versão do Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selecionar codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Taxa de amostra do áudio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quando ativada, o Wi-Fi será mais agressivo em passar a conexão de dados para móvel, quando o sinal de Wi-Fi estiver fraco"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permitir/proibir verificações de roaming de Wi-Fi com base no volume do tráfego de dados presente na interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Sel. tam. de logger/buffer de log"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa em CA"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa por USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa sem fio"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Ativada pelo administrador"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Desativada pelo administrador"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Página inicial das configurações"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 041c6e4ce75a..8ff8eb94420c 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Utilizează verificarea HDCP numai pentru conținut DRM"</item>
<item msgid="45075631231212732">"Utilizează întotdeauna verificarea HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (prestabilit)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Folosiți selectarea sist. (prestabilit)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizat pentru calitatea audio (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Calitatea audio și a conexiunii echilibrată (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimizat pentru calitatea conexiunii (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizat pentru calitatea audio"</item>
- <item msgid="4327143584633311908">"Calitatea audio și a conexiunii echilibrată"</item>
- <item msgid="4681409244565426925">"Optimizat pentru calitatea conexiunii"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Dezactivată"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index caa28ec0380d..507bfc1cd043 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nu se va conecta automat"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nu există acces la internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Salvată de <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectată automat prin %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectată prin %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Foarte rapid"</item>
<item msgid="9085102246155045744">"Cel mai repede"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Alegeți un profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Serviciu"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opțiuni pentru dezvoltatori"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Conectare la rețele"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificare Ecran wireless"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Înregistrare prin Wi-Fi de volume mari de date"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Predare agresivă de la Wi-Fi la mobilă"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Se permite întotdeauna scanarea traficului Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Dezactivați volumul absolut"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versiunea AVRCP pentru Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Selectați versiunea AVRCP pentru Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Selectați codecul audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Rată de eșantionare audio Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmitere în flux: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Când este activată, Wi-Fi va fi mai agresivă la predarea conexiunii de date către rețeaua mobilă când semnalul Wi-Fi este slab"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Permiteți/Nu permiteți scanarea traficului Wi-Fi în funcție de traficul de date din interfață"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Dimensiunile tamponului jurnalului"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Dimensiuni jurnal / tampon jurnal"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Timp rămas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - mai rămân(e) <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă la c.a."</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă prin USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlată de administrator"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Activată de administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Dezactivată de administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ecran principal Setări"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index d366d9c4e12b..0a7f8ac7d8ae 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Использовать проверку HDCP только для DRM-контента"</item>
<item msgid="45075631231212732">"Всегда использовать проверку HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (по умолчанию)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Выбор системы (по умолчанию)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Оптимизировать качество звука (990/909 Кбит/с)"</item>
- <item msgid="2921767058740704969">"Баланс качества звука и скорости подключения (660/606 кбит/с)"</item>
- <item msgid="8860982705384396512">"Оптимизировать скорость подключения (330/303 Кбит/с)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Оптимизировать качество звука"</item>
- <item msgid="4327143584633311908">"Баланс качества звука и скорости подключения"</item>
- <item msgid="4681409244565426925">"Оптимизировать скорость подключения"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Выкл."</item>
<item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 4f53edcb79bb..78cb659f6acc 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Подключение не будет выполняться автоматически"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Отсутствует подключение к Интернету"</string>
<string name="saved_network" msgid="4352716707126620811">"Кто сохранил: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматически подключено к %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Подключено к %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Сильно ускоренная"</item>
<item msgid="9085102246155045744">"Максимальная"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Выберите профиль"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Личные данные"</string>
<string name="category_work" msgid="8699184680584175622">"Работа"</string>
<string name="development_settings_title" msgid="215179176067683667">"Для разработчиков"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Сети"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Серт. беспроводн. мониторов"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Подробный журнал Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Переключаться на мобильную сеть"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Всегда включать поиск сетей Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Отключить абсолютный уровень громкости"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Выберите версию Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Аудиокодек для передачи через Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Аудиокодек для Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частота дискретизации при передаче через Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Потоковая передача: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"При выборе Wi‑Fi указывать в журнале RSSI для каждого SSID"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Принудительно переключаться на мобильную сеть, если сигнал Wi-Fi слабый"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Включать или отключать поиск сетей Wi-Fi во время передачи данных в зависимости от объема трафика"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Размер буфера журнала"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Выберите размер буфера журнала"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Осталось: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось примерно <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>, осталось: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки от сети"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки через USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (беспроводная)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролируется администратором"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Включено администратором"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Отключено администратором"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Настройки"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 124545e71b1e..89b9e80c4aee 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRM අන්තර්ගත සඳහා පමණක් HDCP පරික්ෂාව භාවිතා කරන්න"</item>
<item msgid="45075631231212732">"සැමවිටම HDCP පිරික්සුම භාවිතා කරන්න"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (පෙරනිමි)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"ඒකල"</item>
<item msgid="8883739882299884241">"ස්ටීරියෝ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ශ්‍රව්‍ය ගුණත්වය සඳහා ප්‍රශස්ත කරන ලදී (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"සමබර ශ්‍රව්‍ය සහ සබැඳුම් ගුණත්වය (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"සබැඳුම් ගුණත්වය සඳහා ප්‍රශස්ත කරන ලදී (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ශ්‍රව්‍ය ගුණත්වය සඳහා ප්‍රශස්ත කරන ලදී"</item>
- <item msgid="4327143584633311908">"සමබර ශ්‍රව්‍ය සහ සබැඳුම් ගුණත්වය"</item>
- <item msgid="4681409244565426925">"සබැඳුම් ගුණත්වය සඳහා ප්‍රශස්ත කරන ලදී"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ක්‍රියාවිරහිතය"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 647b0e3c638e..494bce8e7162 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ස්වයංක්‍රිය නැවත සම්බන්ධ නොවනු ඇත"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"අන්තර්ජාල ප්‍රවේශය නැත"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> විසින් සුරකින ලදී"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s හරහා ස්වයංක්‍රියව සම්බන්ධ විය"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s හරහා සම්බන්ධ විය"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"ඉතා ශීඝ්‍ර"</item>
<item msgid="9085102246155045744">"ඉතාම වේගවත්"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"පැතිකඩ තෝරන්න"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"පෞද්ගලික"</string>
<string name="category_work" msgid="8699184680584175622">"කාර්යාලය"</string>
<string name="development_settings_title" msgid="215179176067683667">"වර්ධක විකල්ප"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ජාලකරණය"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"නොරැහැන් සංදර්ශක සහතිකය"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"විස්තරාත්මක Wi‑Fi ලොග් කිරීම සබල කරන්න"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ආක්‍රමණික Wi‑Fi සිට ජංගම බාර දීම"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi රෝම් පරිලෝකන වෙතට සැමවිට අවසර දෙන්න"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්‍රියාකාරීය"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"නිරපේක්ෂ හඩ පරිමාව අබල කරන්න"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"බ්ලූටූත් AVRCP අනුවාදය"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"බ්ලූටූත් AVRCP අනුවාදය තෝරන්න"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"බ්ලූටූත් ශ්‍රව්‍ය Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"බ්ලූටූත් ශ්‍රව්‍ය කොඩෙක් තෝරන්න"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"බ්ලූටූත් ශ්‍රව්‍ය නියැදි අනුපාතය"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ප්‍රවාහ කරමින්: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"සබල විට Wi‑Fi සිග්නලය අඩු විට Wi‑Fi දත්ත සම්බන්ධතාවය ජංගම වෙත භාර දීමට වඩා ආක්‍රමණික වේ"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"අතුරු මුහුණතෙහි ඇති දත්ත තදබදය අනුව Wi‑Fi රෝම් පරිලෝකන වෙත ඉඩ දෙන්න/නොදෙන්න"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ලෝගයේ අන්තරාවක ප්‍රමාණය"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ලොග අන්තරාවකට ලෝගයේ ප්‍රමාණය තෝරන්න"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"දළ වශයෙන් <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරිය"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ඉතිරි <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>ක් පමණ ඇත"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ඉතිරි <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC මත සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB හරහා සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> රැහැන් රහිතව සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"නොදනී"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"පරිපාලක විසින් පාලනය කරන ලදී"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"පරිපාලක විසින් සබල කරන ලදී"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"පරිපාලක විසින් අබල කරන ලදී"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"සැකසීම් මුල් පිටුව"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index c1e85b1bf853..a1c8c31ce818 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Použiť kontrolu HDCP len pre obsah DRM"</item>
<item msgid="45075631231212732">"Vždy používať kontrolu HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (predvolené)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Použiť voľbu systému (predvolené)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimalizovaná kvalita zvuku (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Vyrovnaná kvalita zvuku a pripojenia (660/606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optimalizovaná kvalita pripojenia (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimalizovaná kvalita zvuku"</item>
- <item msgid="4327143584633311908">"Vyrovnaná kvalita zvuku a pripojenia"</item>
- <item msgid="4681409244565426925">"Optimalizovaná kvalita pripojenia"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Vypnuté"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e3f427e25ec3..0334772557f5 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nedôjde k automatickému pripojeniu"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Žiadny prístup k internetu"</string>
<string name="saved_network" msgid="4352716707126620811">"Uložil(a) <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky pripojené prostredníctvom %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Veľmi rýchlo"</item>
<item msgid="9085102246155045744">"Najrýchlejšie"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Výber profilu"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Osobné"</string>
<string name="category_work" msgid="8699184680584175622">"Práca"</string>
<string name="development_settings_title" msgid="215179176067683667">"Pre vývojárov"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Možnosti siete"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikácia bezdrôtového zobrazenia"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. odovzdávať Wi-Fi na mobilnú sieť"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povoliť funkciu Wi-Fi Roam Scans"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázať absolútnu hlasitosť"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzia rozhrania Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Zvoľte verziu rozhrania Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio – kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Vybrať kodek Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio – vzorkovacia frekvencia"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamovanie: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi-Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Keď túto možnosť zapnete, Wi-Fi bude agresívnejšie odovzdávať dátové pripojenie na mobilnú sieť vtedy, keď bude slabý signál Wi-Fi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Povoliť alebo zakázať funkciu Wifi Roam Scans na základe objemu prenosu údajov v rozhraní"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávacia pamäť nástroja denníkov"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Veľkosť vyrovnávacej pamäte nástroja denníkov"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Zostáva cca. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – približný zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia zo zásuvky"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia z USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia z bezdrôt. zdroja"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ovládané správcom"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Povolené správcom"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Zakázané správcom"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Domovská stránka nastavení"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 832c70003cec..4438fdc17093 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Preverjanje HDCP uporabi samo za vsebino DRM"</item>
<item msgid="45075631231212732">"Vedno uporabi preverjanje HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (privzeto)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Uporabi sistemsko izbiro (privzeto)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizirano za kakovost zvoka (990/909 kb/s)"</item>
- <item msgid="2921767058740704969">"Uravnotežena kakovost zvoka in povezave (660/606 kb/s)"</item>
- <item msgid="8860982705384396512">"Optimizirano za kakovost povezave (330/303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizirano za kakovost zvoka"</item>
- <item msgid="4327143584633311908">"Uravnotežena kakovost zvoka in povezave"</item>
- <item msgid="4681409244565426925">"Optimizirano za kakovost povezave"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Izklopljeno"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 95cfba8d9b79..aa1f11d4be45 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Samodejna vnovična vzpostavitev povezave se ne bo izvedla"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ni dostopa do interneta"</string>
<string name="saved_network" msgid="4352716707126620811">"Shranil(-a): <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Samodejno vzpostavljena povezava prek: %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Vzpostavljena povezava prek: %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Zelo naglo"</item>
<item msgid="9085102246155045744">"Najhitreje"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Izbira profila"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Osebno"</string>
<string name="category_work" msgid="8699184680584175622">"Služba"</string>
<string name="development_settings_title" msgid="215179176067683667">"Možnosti za razvijalce"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Omrežja"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Potrdilo brezžičnega zaslona"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogoči podrob. zapis. dnevnika za Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Odločen prehod iz Wi-Fi-ja v mobil. omr."</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vedno omogoči iskanje omrežij Wi-Fi za gostovanje"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogočanje absolutnega praga glasnosti"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Različica profila AVRCP za Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Izberite različico profila AVRCP za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Zvočni kodek za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Izberi zvočni kodek za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Hitrost vzorčenja zvoka prek Bluetootha"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Pretočno predvajanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Če je ta možnost omogočena, Wi-Fi odločneje preda podatkovno povezavo mobilnemu omrežju, ko je signal Wi-Fi šibek."</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Omogoči/onemogoči iskanje omrežij Wi-Fi za gostovanje glede na količino podatkovnega prometa pri vmesniku"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Velikosti medpomn. zapisov. dnevnika"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izberite velikost medpomnilnika dnevnika"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Še <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek vtičnice"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek USB-ja"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek brezžič. poln."</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznano"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Nadzira skrbnik"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Omogočil skrbnik"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogočil skrbnik"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Začetna stran nastavitev"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 15cef4379b77..62bf99b60368 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Përdor kontrollin e HDCP-së vetëm për përmbajtjet DRM"</item>
<item msgid="45075631231212732">"Përdor gjithmonë kontrollin e HDCP-së"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (I parazgjedhur)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimizuar për cilësi audioje (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"Cilësi e balancuar e audios dhe e lidhjes (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"Optimizuar për cilësi lidhjeje (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimizuar për cilësi audioje"</item>
- <item msgid="4327143584633311908">"Cilësi e balancuar e audios dhe e lidhjes"</item>
- <item msgid="4681409244565426925">"Optimizuar për cilësi lidhjeje"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Joaktiv"</item>
<item msgid="1593289376502312923">"64 mijë"</item>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 3b1a5678bdde..7e6317962015 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nuk do të lidhet automatikisht"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Nuk ka qsaje në internet"</string>
<string name="saved_network" msgid="4352716707126620811">"E ruajtur nga <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Lidhur automatikisht përmes %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"E lidhur përmes %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Shumë e shpejtë"</item>
<item msgid="9085102246155045744">"Më e shpejta"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Zgjidh profilin"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personale"</string>
<string name="category_work" msgid="8699184680584175622">"Punë"</string>
<string name="development_settings_title" msgid="215179176067683667">"Opsionet e zhvilluesit"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Rrjetet"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikimi i ekranit valor"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivizo hyrjen Wi-Fi Verbose"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Dorëzimi agresiv i Wi‑Fi te rrjeti celular"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Lejo gjithmonë skanimet për Wi-Fi edhe kur je në lëvizje"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Çaktivizo volumin absolut"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versioni AVRCP i Bluetooth-it"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Zgjidh versionin AVRCP të Bluetooth-it"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodeku Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Zgjidh kodekun e audios së Bluetooth-it"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Shpejtësia e shembullit të Bluetooth Audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmetimi: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kur ky funksion aktivizohet, Wi‑Fi bëhet më agresiv në kalimin e lidhjes së të dhënave te rrjeti celular, në rastet kur sinjali Wi‑Fi është i dobët"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Lejo/Ndalo skanimet për Wi‑Fi në roaming, bazuar në sasinë e trafikut të të dhënave të pranishme në ndërfaqe"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Madhësitë e regjistruesit"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Përzgjidh madhësitë e regjistruesit"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht përmes rrymës së alternuar"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht përmes USB-së"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht me valë"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"I panjohur"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolluar nga administratori"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Aktivizuar nga administratori"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Çaktivizuar nga administratori"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Kreu i cilësimeve"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index b02cc1f5d3a3..147f3db166cc 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Користи HDCP проверу само за DRM садржај"</item>
<item msgid="45075631231212732">"Увек користи HDCP проверу"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (подразумевано)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Користи избор система (подразумевано)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Оптимизовано за квалитет звука (990 kb/s/909 kb/s)"</item>
- <item msgid="2921767058740704969">"Уједначен квалитет звука и везе (660 kb/s/606 kb/s)"</item>
- <item msgid="8860982705384396512">"Оптимизовано за квалитет везе (330 kb/s/303 kb/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Оптимизовано за квалитет звука"</item>
- <item msgid="4327143584633311908">"Уједначен квалитет звука и везе"</item>
- <item msgid="4681409244565426925">"Оптимизовано за квалитет везе"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Искључено"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 1f106b6ae3bc..8680b0861e39 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Аутоматско повезивање није успело"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Нема приступа интернету"</string>
<string name="saved_network" msgid="4352716707126620811">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Аутоматски повезано преко %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Веза је успостављена преко приступне тачке %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Веома убрзано"</item>
<item msgid="9085102246155045744">"Најбрже"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Изаберите профил"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Лично"</string>
<string name="category_work" msgid="8699184680584175622">"Посао"</string>
<string name="development_settings_title" msgid="215179176067683667">"Опције за програмера"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Умрежавање"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сертификација бежичног екрана"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресиван прелаз са Wi‑Fi мреже на мобилну"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Увек дозволи скенирање Wi‑Fi-ја у ромингу"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Онемогући главно подешавање јачине звука"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP-а"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Изаберите верзију Bluetooth AVRCP-а"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth аудио кодек"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Изаберите Bluetooth аудио кодек"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Брзина узорковања за Bluetooth аудио"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Стримовање: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Приказ опција за сертификацију бежичног екрана"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Кад се омогући, Wi‑Fi ће бити агресивнији при пребацивању мреже за пренос података на мобилну ако је Wi‑Fi сигнал слаб"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дозволи/забрани скенирање Wi-Fi-ја у ромингу на основу присутног протока података на интерфејсу"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Величине бафера података у програму за евидентирање"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Изаберите величине по баферу евиденције"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Још отприлике <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Преостало време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – остало је око <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"Преостало је <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења преко утичнице"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења преко USB-а"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења на бежичној мрежи"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Пуњење"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролише администратор"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Омогућио је администратор"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Онемогућио је администратор"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Почетна за Подешавања"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 34c58cb1f172..ea966170534d 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Använd bara HDCP-kontroll för DRM-innehåll"</item>
<item msgid="45075631231212732">"Använd alltid HDCP-kontroll"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Använd systemval (standardinställning)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimerad för ljudkvalitet (990 kbit/s eller 909 kbit/s)"</item>
- <item msgid="2921767058740704969">"Balanserad ljud- och anslutningskvalitet (660 kbit/s/606 kbit/s)"</item>
- <item msgid="8860982705384396512">"Optimerad för anslutningskvalitet (330 kbit/s eller 303 kbit/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimerad för ljudkvalitet"</item>
- <item msgid="4327143584633311908">"Balanserad ljud- och anslutningskvalitet"</item>
- <item msgid="4681409244565426925">"Optimerad för anslutningskvalitet"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Av"</item>
<item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index d873d070bfac..b545039d5be8 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Det går inte att ansluta automatiskt"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Ingen internetåtkomst"</string>
<string name="saved_network" msgid="4352716707126620811">"Sparades av <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiskt ansluten via %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Anslutet via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Turbosnabbt"</item>
<item msgid="9085102246155045744">"Snabbast"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Välj profil"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personligt"</string>
<string name="category_work" msgid="8699184680584175622">"Arbetet"</string>
<string name="development_settings_title" msgid="215179176067683667">"Utvecklaralternativ"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Nätverk"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifiering för Wi-Fi-skärmdelning"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivera utförlig loggning för Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv överlämning fr. Wi-Fi t. mobil"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillåt alltid sökning efter Wi-Fi-roaming"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inaktivera Absolute volume"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version för Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Välj AVRCP-version för Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Ljudkodek för Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Välj Ljudkodek för Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Samplingsfrekvens för Bluetooth-ljud"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"När funktionen har aktiverats kommer dataanslutningen lämnas över från Wi-Fi till mobilen på ett aggressivare sätt när Wi-Fi-signalen är svag"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Tillåt/tillåt inte sökning efter Wi-Fi-roaming utifrån mängden datatrafik i gränssnittet"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Buffertstorlekar för logg"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Välj loggstorlekar per loggbuffert"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca <xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – cirka <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills det är fulladdat"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills fulladdat via AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills fulladdat via USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills fulladdat m. trådlös laddning"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Okänd"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Strys av administratören"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Har aktiverats av administratören"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Har inaktiverats av administratören"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Startskärmen för inställningar"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 9bfc15ca6bff..7a2d277cfafe 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Tumia ukaguaji wa HDCP kwa maudhui ya DRM pekee"</item>
<item msgid="45075631231212732">"Kila wakati tumia ukakuaji wa HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Chaguo-msingi)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Imeimarishwa kwa ajili ya Ubora wa Sauti (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Ubora wa Muunganisho na Sauti Umesawazishwa (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Imeimarishwa kwa ajili ya Ubora wa Muunganisho (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Imeimarishwa kwa ajili ya Ubora wa Sauti"</item>
- <item msgid="4327143584633311908">"Ubora wa Muunganisho na Sauti Umesawazishwa"</item>
- <item msgid="4681409244565426925">"Imeimarishwa kwa ajili ya Ubora wa Muunganisho"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Imezimwa"</item>
<item msgid="1593289376502312923">"K64"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 8a04c9d9f2c7..ce1c057895e9 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Haiwezi kuunganisha kiotomatiki"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Hakuna muunganisho wa Intaneti"</string>
<string name="saved_network" msgid="4352716707126620811">"Ilihifadhiwa na <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Imeunganishwa kiotomatiki kupitia %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Imeunganishwa kupitia %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Kasi sana"</item>
<item msgid="9085102246155045744">"Kasi zaidi"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Chagua Wasifu"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Ya Kibinafsi"</string>
<string name="category_work" msgid="8699184680584175622">"Kazini"</string>
<string name="development_settings_title" msgid="215179176067683667">"Chaguo za wasanidi"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Mtandao"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Chaguo za cheti cha kuonyesha pasiwaya"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Washa Uwekaji kumbukumbu za WiFi kutumia Sauti"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukabidhi hima kutoka Wifi kwenda mtandao wa simu"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Ruhusu Uchanganuzi wa Matumizi ya Mitandao mingine"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zima sauti kamili"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Toleo la Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Chagua Toleo la Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Kodeki ya Sauti ya Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Chagua Kodeki ya Sauti ya Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Kiwango cha Sampuli ya Sauti ya Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Kutiririsha: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ikiwashwa, Wi-Fi itakabidhi kwa hima muunganisho wa data kwa mtandao wa simu, wakati mtandao wa Wi-Fi si thabiti"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Ruhusu au Zuia Uchanganuzi wa Matumizi ya Mitandao mingine ya Wifi kulingana na kiasi cha trafiki ya data kilicho kwenye kiolesura"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Ukubwa wa kiweka bafa ya kumbukumbu"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Chagua ukubwa wa kila Kumbukumbu"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takribani <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"Imechaji <xliff:g id="LEVEL">%1$s</xliff:g> - Zimesalia <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji ukitumia AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji ukitumia USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji bila kutumia waya"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Haijulikani"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Imedhibitiwa na msimamizi"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Msimamizi amewasha mapendeleo ya mipangilio"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Msimamizi amezima mapendeleo ya mipangilio"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ukurasa wa Kwanza wa Mipangilio"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index c50ea1d500dd..1dfcc4d558fb 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -116,16 +116,8 @@
<item msgid="8900559293912978337">"மோனோ"</item>
<item msgid="8883739882299884241">"ஸ்டீரியோ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ஆடியோ தரத்திற்காக மேம்படுத்தியது (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"சமன்படுத்தப்பட்ட ஆடியோ மற்றும் இணைப்புத் தரம் (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"இணைப்புத் தரத்திற்காக மேம்படுத்தியது (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ஆடியோ தரத்திற்காக மேம்படுத்தியது"</item>
- <item msgid="4327143584633311908">"சமன்படுத்தப்பட்ட ஆடியோ மற்றும் இணைப்புத் தரம்"</item>
- <item msgid="4681409244565426925">"இணைப்புத் தரத்திற்காக மேம்படுத்தியது"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"முடக்கு"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 262fa1141c05..5c0cd9f80a76 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -34,7 +34,7 @@
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> சேமித்தது"</string>
<!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
<skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s வழியாக இணைக்கப்பட்டது"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string>
@@ -141,7 +141,8 @@
<item msgid="5194774745031751806">"மிக அதிக வேகமாக"</item>
<item msgid="9085102246155045744">"அதிகபட்ச வேகம்"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"சுயவிவரத்தைத் தேர்வுசெய்யவும்"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"தனிப்பட்டவை"</string>
<string name="category_work" msgid="8699184680584175622">"பணியிடம்"</string>
<string name="development_settings_title" msgid="215179176067683667">"டெவெலப்பர் விருப்பங்கள்"</string>
@@ -353,8 +354,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"நிர்வாகி இயக்கியுள்ளார்"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"நிர்வாகி முடக்கியுள்ளார்"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"அமைப்புகள் முகப்பு"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 2cd556401ce7..87919d252b1c 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"DRM కంటెంట్‌కు మాత్రమే HDCP తనిఖీని ఉపయోగించండి"</item>
<item msgid="45075631231212732">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించు"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (డిఫాల్ట్)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"మోనో"</item>
<item msgid="8883739882299884241">"స్టీరియో"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"ఆడియో నాణ్యత (990kbps/909kbps) కోసం అనుకూలీకరించబడింది"</item>
- <item msgid="2921767058740704969">"సమతుల్య ఆడియో మరియు కనెక్షన్ నాణ్యత (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"కనెక్షన్ నాణ్యత (330kbps/303kbps) కోసం అనుకూలీకరించబడింది"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"ఆడియో నాణ్యత కోసం అనుకూలీకరించబడింది"</item>
- <item msgid="4327143584633311908">"సమతుల్య ఆడియో మరియు కనెక్షన్ నాణ్యత"</item>
- <item msgid="4681409244565426925">"కనెక్షన్ నాణ్యత కోసం అనుకూలీకరించబడింది"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ఆఫ్"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index b18c23fa7c77..0bbf6ca7a9c3 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"స్వయంచాలకంగా కనెక్ట్ కాదు"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ఇంటర్నెట్ ప్రాప్యత లేదు"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా సేవ్ చేయబడింది"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"అత్యంత వేగం"</item>
<item msgid="9085102246155045744">"అత్యంత వేగవంతం"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"ప్రొఫైల్‌ను ఎంచుకోండి"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"వ్యక్తిగతం"</string>
<string name="category_work" msgid="8699184680584175622">"కార్యాలయం"</string>
<string name="development_settings_title" msgid="215179176067683667">"డెవలపర్ ఎంపికలు"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"నెట్‌వర్కింగ్"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"వైర్‌లెస్ ప్రదర్శన ప్రమాణీకరణ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi విశదీకృత లాగింగ్‌ను ప్రారంభించండి"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"మొబైల్‌కి మార్చేలా చురుకైన Wi‑Fi"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi సంచార స్కాన్‌లను ఎల్లప్పుడూ అనుమతించు"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ సక్రియంగా ఉంచు"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"సంపూర్ణ వాల్యూమ్‌‍ను నిలిపివేయి"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"బ్లూటూత్ AVRCP సంస్కరణ"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"బ్లూటూత్ AVRCP సంస్కరణను ఎంచుకోండి"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"బ్లూటూత్ ఆడియో కోడెక్"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"బ్లూటూత్ ఆడియో కోడెక్‌ని ఎంచుకోండి"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"బ్లూటూత్ ఆడియో నమూనా రేట్"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ప్రసారం చేస్తోంది: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్‌లెస్ ప్రదర్శన ప్రమాణపత్రం కోసం ఎంపికలను చూపు"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ప్రారంభించబడినప్పుడు, Wi‑Fi సిగ్నల్ బలహీనంగా ఉంటే డేటా కనెక్షన్‌ను మొబైల్‌కి మార్చేలా Wi‑Fi చురుగ్గా వ్యవహరిస్తుంది"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"ఇంటర్‌ఫేస్‌లో ఉండే డేటా ట్రాఫిక్ పరిమాణం ఆధారంగా Wi‑Fi సంచార స్కాన్‌లను అనుమతించు/నిరాకరించు"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"లాగర్ బఫర్ పరిమాణాలు"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"లాగ్ బఫర్‌కి లాగర్ పరిమా. ఎంచుకోండి"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో ACతో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో USB ద్వారా పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో వైర్‌లెస్‌లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"తెలియదు"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"నిర్వాహకులు ప్రారంభించారు"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"నిర్వాహకులు నిలిపివేసారు"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"సెట్టింగ్‌ల హోమ్"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 26f231674113..fc3fd97011d0 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"ใช้การตรวจสอบ HDCP สำหรับเนื้อหา DRM เท่านั้น"</item>
<item msgid="45075631231212732">"ใช้การตรวจสอบ HDCP เสมอ"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (ค่าเริ่มต้น)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"โมโน"</item>
<item msgid="8883739882299884241">"สเตอริโอ"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"เพิ่มประสิทธิภาพสำหรับคุณภาพเสียง (990 kbps/909 kbps)"</item>
- <item msgid="2921767058740704969">"คุณภาพเสียงและการเชื่อมต่อที่สมดุล (660 kbps/606 kbps)"</item>
- <item msgid="8860982705384396512">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ (330 kbps/303 kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"เพิ่มประสิทธิภาพสำหรับคุณภาพเสียง"</item>
- <item msgid="4327143584633311908">"คุณภาพเสียงและการเชื่อมต่อที่สมดุล"</item>
- <item msgid="4681409244565426925">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"ปิด"</item>
<item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index c8470e5f9f22..ea71092c5f85 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"จะไม่เชื่อมต่อโดยอัตโนมัติ"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"ไม่สามารถเข้าถึงอินเทอร์เน็ต"</string>
<string name="saved_network" msgid="4352716707126620811">"บันทึกโดย <xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"เชื่อมต่ออัตโนมัติผ่าน %1$s แล้ว"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"เร็วมาก"</item>
<item msgid="9085102246155045744">"เร็วที่สุด"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"เลือกโปรไฟล์"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ส่วนตัว"</string>
<string name="category_work" msgid="8699184680584175622">"ที่ทำงาน"</string>
<string name="development_settings_title" msgid="215179176067683667">"สำหรับนักพัฒนาซอฟต์แวร์"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"เครือข่าย"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"การรับรองการแสดงผลแบบไร้สาย"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"เปิดใช้การบันทึกรายละเอียด Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"สลับ Wi‑Fi เป็นมือถือเมื่อสัญญาณอ่อน"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ใช้การสแกน Wi-Fi ข้ามเครือข่ายเสมอ"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้อินเทอร์เน็ตมือถือเสมอ"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ปิดใช้การควบคุมระดับเสียงของอุปกรณ์อื่น"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"เวอร์ชันของบลูทูธ AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"เลือกเวอร์ชันของบลูทูธ AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ตัวแปลงรหัสเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"เลือกตัวแปลงรหัสเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"อัตราตัวอย่างเสียงบลูทูธ"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"สตรีมมิง: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"เมื่อเปิดใช้แล้ว Wi-Fi จะส่งผ่านการเชื่อมต่อข้อมูลไปยังเครือข่ายมือถือเมื่อสัญญาณ Wi-Fi อ่อน"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"อนุญาต/ไม่อนุญาตการสแกน Wi-Fi ข้ามเครือข่าย ตามปริมาณข้อมูลการเข้าชมที่ปรากฏในอินเทอร์เฟซ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ขนาดบัฟเฟอร์ของ Logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"เลือกขนาด Logger ต่อบัฟเฟอร์ไฟล์บันทึก"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"เหลืออีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"เหลืออีก <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือเวลาประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลืออีก <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็ม"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็มผ่าน AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็มผ่าน USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็มผ่านระบบไร้สาย"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"เปิดใช้โดยผู้ดูแลระบบ"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"ปิดใช้โดยผู้ดูแลระบบ"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"หน้าแรกของการตั้งค่า"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index eeec945be525..414fca94ed48 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Gamitin lang ang pagsusuring HDCP para sa nilalamang DRM"</item>
<item msgid="45075631231212732">"Palaging gumamit ng pagsusuring HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Gamitin ang Pagpili ng System (Default)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Naka-optimize para sa Kalidad ng Audio (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanse ang Kalidad ng Audio at Koneksyon (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Naka-optimize para sa Kalidad ng Koneksyon (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Naka-optimize para sa Kalidad ng Audio"</item>
- <item msgid="4327143584633311908">"Balanse ang Kalidad ng Audio at Koneksyon"</item>
- <item msgid="4681409244565426925">"Naka-optimize para sa Kalidad ng Koneksyon"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"I-off"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index b5f558d8a801..48934e43b3c5 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Hindi awtomatikong kokonekta"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Walang access sa Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Na-save ni <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Awtomatikong nakakonekta sa pamamagitan ng %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Nakakonekta sa pamamagitan ng %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Napakatulin"</item>
<item msgid="9085102246155045744">"Pinakamabilis"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Pumili ng Profile"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Personal"</string>
<string name="category_work" msgid="8699184680584175622">"Trabaho"</string>
<string name="development_settings_title" msgid="215179176067683667">"Mga opsyon ng developer"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certification ng wireless display"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"I-enable ang Pagla-log sa Wi‑Fi Verbose"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresibong paglipat ng Wi‑Fi sa mobile"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Palaging payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"I-disable ang absolute volume"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bersyon ng AVRCP ng Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Pumili ng Bersyon ng AVRCP ng Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Piliin ang Audio Codec ng Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Sample na Rate ng Bluetooth Audio"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kapag na-enable, magiging mas agresibo ang Wi‑Fi sa paglipat sa koneksyon ng mobile data kapag mahina ang signal ng Wi‑Fi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Payagan/Huwag payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi batay sa dami ng trapiko ng data na mayroon sa interface"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Mga laki ng buffer ng Logger"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Pumili ng mga laki ng Logger bawat log buffer"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> na lang ang natitira"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> pa"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit-kumulang <xliff:g id="TIME">%2$s</xliff:g> pa ang natitira"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> pa"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa makumpleto ang charge"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa matapos mag-charge sa AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa matapos mag-charge sa USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa matapos mag-charge sa wireless"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Hindi Kilala"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pinapamahalaan ng admin"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Na-enable ng administrator"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Na-disable ng administrator"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Home ng Mga Setting"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 6519a11ea25a..aea0525e8c97 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP denetimini yalnızca DRM içeriği için kullan"</item>
<item msgid="45075631231212732">"HDCP denetimini her zaman kullan"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Varsayılan)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Sistem Seçimini Kullan (Varsayılan)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Ses Kalitesi (990 kb/sn. / 909 kb/sn.) için optimize edildi"</item>
- <item msgid="2921767058740704969">"Dengeli Ses ve Bağlantı Kalitesi (660 kb/sn. / 606 kb/sn.)"</item>
- <item msgid="8860982705384396512">"Bağlantı Kalitesi (330 kb/sn. / 303 kb/sn.) için optimize edildi"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Ses Kalitesi için optimize edildi"</item>
- <item msgid="4327143584633311908">"Dengeli Ses ve Bağlantı Kalitesi"</item>
- <item msgid="4681409244565426925">"Bağlantı Kalitesi için optimize edildi"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Kapalı"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 6a35f949f814..77a3bb4e7ee2 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Otomatik olarak bağlanma"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"İnternet erişimi yok"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> tarafından kaydedildi"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s üzerinden otomatik olarak bağlı"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s üzerinden bağlı"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Çok seri"</item>
<item msgid="9085102246155045744">"En hızlı"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profil Seçin"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Kişisel"</string>
<string name="category_work" msgid="8699184680584175622">"İş"</string>
<string name="development_settings_title" msgid="215179176067683667">"Geliştirici seçenekleri"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Ağ işlemleri"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Kablosuz ekran sertifikası"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Kablosuzdan mobil ağa agresif geçiş"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Kablosuz Dolaşım Taramalarına daima izin ver"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mutlak sesi iptal et"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Sürümü"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP Sürümünü seçin"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Ses Codec\'i"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth Ses Codec\'ini Seçin"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Ses Örnek Hızı"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Akış: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Etkinleştirildiğinde, kablosuz ağ sinyali zayıfken veri bağlantısının mobil ağa geçirilmesinde daha agresif olunur"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Arayüzde mevcut veri trafiği miktarına bağlı olarak Kablosuz Dolaşım Taramalarına İzin Verin/Vermeyin"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Günlük Kaydedici arabellek boyutları"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Gün. arabel. başına Gün. Kayd. boyutunu seç"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - Prize bağlı, tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ile tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kablosuz ile tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Bilinmiyor"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Yönetici tarafından denetleniyor"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Yönetici tarafından etkinleştirildi"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Yönetici tarafından devre dışı bırakıldı"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ayarlar Ana Sayfası"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"%0"</item>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 961119e6379c..6bbae3d62664 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Використовувати перевірку HDCP лише для вмісту, захищеного DRM"</item>
<item msgid="45075631231212732">"Завжди використовувати перевірку HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (за умовчанням)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Використовувати вибір системи (за умовчанням)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Моно"</item>
<item msgid="8883739882299884241">"Стерео"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Оптимізовано для кращої якості аудіо (990/909 кбіт/с)"</item>
- <item msgid="2921767058740704969">"Збалансована якість аудіо та з’єднання (660/606 кбіт/с)"</item>
- <item msgid="8860982705384396512">"Оптимізовано для кращої якості з’єднання (330/303 кбіт/с)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Оптимізовано для кращої якості аудіо"</item>
- <item msgid="4327143584633311908">"Збалансована якість аудіо та з’єднання"</item>
- <item msgid="4681409244565426925">"Оптимізовано для кращої якості з’єднання"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Вимкнено"</item>
<item msgid="1593289376502312923">"64 Кб"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 97b286d916ae..eda466be3d15 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не під’єднуватиметься автоматично"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Немає доступу до Інтернету"</string>
<string name="saved_network" msgid="4352716707126620811">"Збережено додатком <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматично під’єднано через %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Під’єднано через %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Украй швидко"</item>
<item msgid="9085102246155045744">"Найшвидше"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Вибрати профіль"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Особисте"</string>
<string name="category_work" msgid="8699184680584175622">"Робота"</string>
<string name="development_settings_title" msgid="215179176067683667">"Параметри розробника"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Мережі"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сертифікація бездрот. екрана"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Докладний запис у журнал Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Перемикатися з Wi-Fi на мобільну мережу"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Завжди шукати мережі Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Вимкнути абсолютну гучність"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Виберіть версію Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодек для аудіо Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Вибрати кодек для аудіо Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частота вибірки для аудіо Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляція: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Примусово перемикатися на мобільну мережу, коли сигнал Wi-Fi слабкий"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дозволити чи заборонити Wi-Fi шукати роумінг на основі обсягу трафіку даних в інтерфейсі"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Розміри буфера журналу"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Виберіть розміри буфера журналу"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Залишилося приблизно <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ще <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилося <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду від розетки"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду через USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду від бездротового пристрою"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Невідомо"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядж-ся"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Керується адміністратором"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Увімкнено адміністратором"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Вимкнено адміністратором"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Головний екран налаштувань"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index ad111cc229c1..432a6dc280cc 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"‏HDCP چیکنگ صرف DRM مواد کیلئے استعمال کریں"</item>
<item msgid="45075631231212732">"‏ہمیشہ HDCP چیکنگ استعمال کریں"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"‏AVRCP 1.4 (ڈیفالٹ)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"مونو"</item>
<item msgid="8883739882299884241">"اسٹیریو"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"‏آڈیو کے معیار کیلئے بہتر بنایا گيا (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"‏متوازن آڈیو اور کنکشن کا معیار (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"‏کنکشن کے معیار کیلئے بہتر بنایا گيا (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"آڈیو کے معیار کیلئے بہتر بنایا گيا"</item>
- <item msgid="4327143584633311908">"متوازن آڈیو اور کنکشن کا معیار"</item>
- <item msgid="4681409244565426925">"کنکشن کے معیار کیلئے بہتر بنایا گيا"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"آف"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 15ff61b62b85..7933ca4c65fb 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"خودکار طور پر منسلک نہیں ہو گا"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"انٹرنیٹ تک کوئی رسائی نہیں"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> کی جانب سے محفوظ کردہ"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"‏‎%1$s کے ذریعے از خود منسلک کردہ"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"‏منسلک بذریعہ ‎%1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"‏دستیاب بذریعہ ‎%1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"کافی تیز"</item>
<item msgid="9085102246155045744">"تیز ترین"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"پروفائل منتخب کریں"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"ذاتی"</string>
<string name="category_work" msgid="8699184680584175622">"دفتر"</string>
<string name="development_settings_title" msgid="215179176067683667">"ڈویلپر کے اختیارات"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"نیٹ ورکنگ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"وائرلیس ڈسپلے سرٹیفیکیشن"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"‏Wi‑Fi وربوس لاگنگ فعال کریں"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏Wi‑Fi سے موبائل کو جارحانہ ہینڈ اوور"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏ہمیشہ Wi‑Fi روم اسکینز کی اجازت دیں"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"مطلق والیوم کو غیر فعال کریں"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏بلوٹوتھ AVRCP ورژن"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"‏بلوٹوتھ AVRCP ورژن منتخب کریں"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"بلوٹوتھ آڈیو کوڈیک"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"بلوٹوتھ آڈیو کوڈیک منتخب کریں"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"بلوٹوتھ آڈیو کے نمونے کی شرح"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"سلسلہ بندی: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"‏فعال کئے جانے پر، جب Wi‑Fi سگنل کمزور ہوگا، تو Wi‑Fi موبائل پر ڈیٹا کنکشن بھیجنے کیلئے مزید جارحانہ کارروائی کرے گا"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"‏انٹرفیس پر موجود ڈیٹا ٹریفک کی مقدار کی بنیاد پر Wi‑Fi روم اسکینز کی اجازت دیں/اجازت نہ دیں"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"لاگر بفر کے سائز"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"فی لاگ بفر لاگر کے سائز منتخب کریں"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریبا <xliff:g id="TIME">%1$s</xliff:g> باقی ہیں"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
<string name="power_charging" msgid="1779532561355864267">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> پوری طرح چارج ہونے تک"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC پر پوری طرح چارج ہونے تک"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB پر پوری طرح چارج ہونے تک"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> وائر لیس سے پوری طرح چارج ہونے تک"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"نامعلوم"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"کنٹرول کردہ بذریعہ منتظم"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"منتظم نے فعال کر دیا"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"منتظم نے غیر فعال کر دیا"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"ترتیبات ہوم"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 9d8c5b0600f0..1ee282312022 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"HDCP tekshiruvi faqat DRM kontent uchun ishlatilsin"</item>
<item msgid="45075631231212732">"Har doim HDCP tekshiruvidan foydalanilsin"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (asosiy)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Tizim tanlovi (birlamchi)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Mono"</item>
<item msgid="8883739882299884241">"Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Ovoz sifatini optimallashtirish (990/909 kbit/s)"</item>
- <item msgid="2921767058740704969">"Audio sifati balansi va ulanish tezligi (660/606 kbit/s)"</item>
- <item msgid="8860982705384396512">"Ulanish tezligini optimallashtirish (330/303 kbit/s)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Ovoz sifatini optimallashtirish"</item>
- <item msgid="4327143584633311908">"Audio sifati balansi va ulanish tezligi"</item>
- <item msgid="4681409244565426925">"Ulanish tezligini optimallashtirish"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"O‘chiq"</item>
<item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 7a395ed738db..93adf3b11ab0 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Avtomatik ravishda ulanilmaydi"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Internet aloqasi yo‘q"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> tomonidan saqlangan"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s orqali avtomatik ulandi"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s orqali ulangan"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Juda tez"</item>
<item msgid="9085102246155045744">"Eng tez"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Profil tanlash"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Shaxsiy"</string>
<string name="category_work" msgid="8699184680584175622">"Ish"</string>
<string name="development_settings_title" msgid="215179176067683667">"Dasturchi sozlamalari"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Tarmoqlar"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz monitor sertifikatlari"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Batafsil Wi-Fi jurnali"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mobil internetga o‘tish"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi tarmoqlarini qidirishga doim ruxsat"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet o‘chirilmasin"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Ovoz balangligining mutlaq darajasini o‘chirib qo‘yish"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versiyasi"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Bluetooth AVRCP versiyasini tanlang"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodeki"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Bluetooth orqali uzatish uchun audiokodek"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth audio namunasi chastotasi"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Translatsiya: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Agar ushbu funksiya yoqilsa, Wi-Fi signali past bo‘lganda internetga ulanish majburiy ravishda mobil internetga o‘tkaziladi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Ma’lumotlarni uzatish vaqtida trafik hajmiga qarab Wi-Fi tarmoqlarni qidirish funksiyasini yoqish yoki o‘chirish"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Jurnal buferi hajmi"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Jurnal xotirasi hajmini tanlang"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> – AC orqali to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> – USB orqali to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> – simsiz to‘liq quvvatlashga <xliff:g id="TIME">%2$s</xliff:g> ketadi"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administrator tomonidan boshqariladi"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Administrator tomonidan yoqilgan"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Administrator tomonidan o‘chirilgan"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Sozlamalar"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 5e34660df1f4..3391f21347e8 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Chỉ sử dụng kiểm tra HDCP cho nội dung DRM"</item>
<item msgid="45075631231212732">"Luôn sử dụng kiểm tra HDCP"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Mặc định)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Sử dụng lựa chọn hệ thống (Mặc định)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Đơn âm"</item>
<item msgid="8883739882299884241">"Âm thanh nổi"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Được tối ưu hóa cho chất lượng âm thanh (990kb/giây/909kb/giây)"</item>
- <item msgid="2921767058740704969">"Chất lượng kết nối và âm thanh cân bằng (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Được tối ưu hóa cho chất lượng kết nối (330kb/giây/303kb/giây)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Được tối ưu hóa cho chất lượng âm thanh"</item>
- <item msgid="4327143584633311908">"Chất lượng kết nối và âm thanh cân bằng"</item>
- <item msgid="4681409244565426925">"Được tối ưu hóa cho chất lượng kết nối"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Tắt"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 95a5281e9973..cedb8a9712cd 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Sẽ không tự động kết nối"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Không có quyền truy cập Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Được lưu bởi <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Tự động được kết nối qua %1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Được kết nối qua %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Rất nhanh"</item>
<item msgid="9085102246155045744">"Nhanh nhất"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Chọn hồ sơ"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Cá nhân"</string>
<string name="category_work" msgid="8699184680584175622">"Cơ quan"</string>
<string name="development_settings_title" msgid="215179176067683667">"Tùy chọn nhà phát triển"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Mạng"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Chứng nhận hiển thị không dây"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Bật ghi nhật ký chi tiết Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Chuyển vùng Wi‑Fi tích cực sang mạng DĐ"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luôn cho phép quét chuyển vùng Wi‑Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hiện hoạt"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Vô hiệu hóa âm lượng tuyệt đối"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth phiên bản AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Chọn Bluetooth phiên bản AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Codec âm thanh Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Chọn Codec âm thanh Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Tốc độ lấy mẫu âm thanh Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Truyền trực tuyến: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Khi được bật, Wi‑Fi sẽ tích cực hơn trong việc chuyển vùng kết nối dữ liệu sang mạng di động khi tín hiệu Wi‑Fi yếu"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Cho phép/Không cho phép quét chuyển vùng Wi‑Fi dựa trên lưu lượng truy cập dữ liệu có tại giao diện"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Kích cỡ tải trình ghi"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Chọn kích thước Trình ghi/lần tải nhật ký"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Còn lại <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn lại <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy trên AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy qua USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy từ không dây"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Do quản trị viên kiểm soát"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Được bật bởi quản trị viên"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Bị tắt bởi quản trị viên"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Trang chủ cài đặt"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 5691c5ea56d6..7664328802db 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"仅使用 HDCP 检查 DRM 内容"</item>
<item msgid="45075631231212732">"始终使用 HDCP 检查"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4(默认)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"使用系统选择(默认)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"单声道"</item>
<item msgid="8883739882299884241">"立体声"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"偏重音频质量 (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"兼顾音频和连接质量 (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"偏重连接质量 (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"偏重音频质量"</item>
- <item msgid="4327143584633311908">"兼顾音频和连接质量"</item>
- <item msgid="4681409244565426925">"偏重连接质量"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"关闭"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 369260b4af6f..d88d356e46b4 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"无法自动连接"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"无法连接到互联网"</string>
<string name="saved_network" msgid="4352716707126620811">"已通过<xliff:g id="NAME">%1$s</xliff:g>保存"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"已通过%1$s自动连接"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"极快"</item>
<item msgid="9085102246155045744">"最快"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"选择个人资料"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"个人"</string>
<string name="category_work" msgid="8699184680584175622">"工作"</string>
<string name="development_settings_title" msgid="215179176067683667">"开发者选项"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"网络"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"无线显示认证"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"启用WLAN详细日志记录功能"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"主动从 WLAN 网络切换到移动数据网络"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允许WLAN漫游扫描"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用绝对音量功能"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"蓝牙 AVRCP 版本"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"选择蓝牙 AVRCP 版本"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"蓝牙音频编解码器"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"选择蓝牙音频编解码器"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"蓝牙音频采样率"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"正在流式传输:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升WLAN日志记录级别(在WLAN选择器中显示每个SSID的RSSI)"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"开启此设置后,系统会在 WLAN 信号较弱时,主动将网络模式从 WLAN 网络切换到移动数据网络"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根据接口中目前的数据流量允许/禁止WLAN漫游扫描"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"日志记录器缓冲区大小"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"选择每个日志缓冲区的日志记录器大小"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"还可用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大约还剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满(交流电充电)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满(USB 充电)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满(无线充电)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"由管理员控制"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"已被管理员启用"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"已被管理员禁用"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"设置主屏幕"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 92fb80ff3db6..a50a3d0fee9e 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"僅使用 HDCP 檢查 DRM 內容"</item>
<item msgid="45075631231212732">"永遠使用 HDCP 檢查"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"使用系統選擇 (預設)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"單聲道"</item>
<item msgid="8883739882299884241">"立體聲"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"已優化音訊品質 (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"平衡音訊和連線品質 (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"已優化連線品質 (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"已優化音訊品質"</item>
- <item msgid="4327143584633311908">"平衡音訊和連線品質"</item>
- <item msgid="4681409244565426925">"已優化連線品質"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"關閉"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 270543fbb985..558475e4ab6e 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"不會自動連線"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"無法偵測互聯網連線"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> 的儲存"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"極快"</item>
<item msgid="9085102246155045744">"最快"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"選擇設定檔"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"個人"</string>
<string name="category_work" msgid="8699184680584175622">"公司"</string>
<string name="development_settings_title" msgid="215179176067683667">"開發人員選項"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"網絡"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"加強 Wi-Fi 至流動數據轉換"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"永遠允許 Wi-Fi 漫遊掃瞄"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"選擇藍牙 AVRCP 版本"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"藍牙音訊編解碼器"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"選擇藍牙音訊編解碼器"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"藍牙音訊取樣率"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"正在串流:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用後,Wi-Fi 連線會在訊號不穩定的情況下更積極轉換成流動數據連線"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根據介面中目前的數據流量允許/禁止 WiFi 漫遊掃瞄"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"選取每個記錄緩衝區的記錄器空間"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"尚餘大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 剩餘約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電 (透過 AC)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電 (透過 USB)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能完全充電 (透過無線方式)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"已由管理員啟用"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"已由管理員停用"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"主設定畫面"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index addc48d927d3..db93cc966bf6 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"僅使用 HDCP 檢查 DRM 內容"</item>
<item msgid="45075631231212732">"一律使用 HDCP 檢查"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"使用系統選擇 (預設)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"單聲道"</item>
<item msgid="8883739882299884241">"立體聲"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"音訊品質最佳化 (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"兼顧音訊及連線品質 (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"連線品質最佳化 (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"音訊品質最佳化"</item>
- <item msgid="4327143584633311908">"兼顧音訊及連線品質"</item>
- <item msgid="4681409244565426925">"連線品質最佳化"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"關閉"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 3517c0c4c9ff..0e7c096b90fb 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"無法自動連線"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"沒有可用的網際網路連線"</string>
<string name="saved_network" msgid="4352716707126620811">"由<xliff:g id="NAME">%1$s</xliff:g>儲存"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"極快"</item>
<item msgid="9085102246155045744">"最快"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"選擇設定檔"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"個人"</string>
<string name="category_work" msgid="8699184680584175622">"公司"</string>
<string name="development_settings_title" msgid="215179176067683667">"開發人員選項"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"網路連線"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細紀錄設定"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi 至行動數據轉換強化"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允許 Wi-Fi 漫遊掃描"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"選取藍牙 AVRCP 版本"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"藍牙音訊轉碼器"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"選取藍牙音訊轉碼器"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"藍牙音訊取樣率"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"串流中:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用時,Wi-Fi 連線在訊號不穩的情況下會更積極轉換成行動數據連線"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"根據介面中目前的數據流量允許/禁止 Wi-Fi 漫遊掃描"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"紀錄器緩衝區空間"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"選取每個紀錄緩衝區的紀錄器空間"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"還剩大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"還剩 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 約剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (AC 變壓器充電)"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (USB 充電)"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (無線充電)"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"已由管理員啟用"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"已由管理員停用"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"設定主畫面"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index 9d26eeff8c2b..6a0cc420f315 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -58,12 +58,16 @@
<item msgid="3878793616631049349">"Sebenzisa ukuhlola kwe-HDCP kokuqukethwe i-DRM kuphela"</item>
<item msgid="45075631231212732">"Sebenzisa njalo ukuhlola kwe-HDPC"</item>
</string-array>
- <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
- <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
- <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
- <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
- <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
- <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"I-AVRCP 1.4 (Okuzenzakalelayo)"</item>
+ <item msgid="2089555299377409443">"I-AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"I-AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"I-avrcp14"</item>
+ <item msgid="1913619118958233129">"I-avrcp15"</item>
+ <item msgid="7142710449249088270">"I-avrcp16"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="7065842274271279580">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
<item msgid="7539690996561263909">"SBC"</item>
@@ -116,16 +120,8 @@
<item msgid="8900559293912978337">"Okukodwa"</item>
<item msgid="8883739882299884241">"I-Stereo"</item>
</string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Kuthuthukiselwe ikhwalithi yomsindo (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Umsindo obhalansile nekhwalithi yoxhumo (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Kuthuthukiselwe ikhwalithi yoxhumo (330kbps/303kbps)"</item>
- </string-array>
- <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Kuthuthukiselwe ikhwalithi yomsebenzisi"</item>
- <item msgid="4327143584633311908">"Umsindo obhalansile nekhwalithi yoxhumo"</item>
- <item msgid="4681409244565426925">"Kuthuthukiselwe ikhwalithi yoxhumo"</item>
- </string-array>
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_titles:3 (4414060457677684127) -->
+ <!-- no translation found for bluetooth_a2dp_codec_ldac_playback_quality_summaries:3 (364670732877872677) -->
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Valiwe"</item>
<item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f3dd8f386f33..42c322bfc02b 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -32,9 +32,8 @@
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Ngeke ize ixhumeke ngokuzenzakalela"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Akukho ukufinyelela ku-inthanethi"</string>
<string name="saved_network" msgid="4352716707126620811">"Kulondolozwe ngu-<xliff:g id="NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
- <skip />
- <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ixhumeke ngokuzenzakalela nge-%1$s"</string>
+ <!-- no translation found for connected_via_network_scorer_default (7867260222020343104) -->
<skip />
<string name="connected_via_passpoint" msgid="2826205693803088747">"Kuxhumeke nge-%1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string>
@@ -141,7 +140,8 @@
<item msgid="5194774745031751806">"Esheshisa kakhulu"</item>
<item msgid="9085102246155045744">"Esheshisa kakhulukhulu"</item>
</string-array>
- <string name="choose_profile" msgid="8229363046053568878">"Khetha iphrofayela"</string>
+ <!-- no translation found for choose_profile (6921016979430278661) -->
+ <skip />
<string name="category_personal" msgid="1299663247844969448">"Okomuntu siqu"</string>
<string name="category_work" msgid="8699184680584175622">"Umsebenzi"</string>
<string name="development_settings_title" msgid="215179176067683667">"Izinketho Zonjiniyela"</string>
@@ -170,16 +170,12 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Ukunethiwekha"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Ukunikezwa isitifiketi sokubukeka okungenantambo"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Nika amandlaukungena kwe-Wi-Fi Verbose"</string>
- <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
- <skip />
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukudluliselwa okunamandla kakhulu kwe-Wi-Fi ukuya kuselula"</string>
<string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vumela njalo ukuskena kokuzula kwe-Wi-Fi"</string>
- <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
- <skip />
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Khubaza ivolumu ngokuphelele"</string>
- <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
- <skip />
- <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
- <skip />
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Inguqulo ye-Bluetooth ye-AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Khetha inguqulo ye-Bluetooth AVRCP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"I-Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Khetha i-Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Isilinganiso sesampula yomsindo we-Bluetooth"</string>
@@ -193,8 +189,7 @@
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Ukusakaza: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string>
- <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
- <skip />
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Uma inikwe amandla, i-Wi-Fi izoba namandla kakhulu ekudluliseleni ukuxhumeka kwedatha kuselula, uma isignali ye-Wi-Fi iphansi"</string>
<string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Vumela/Ungavumeli ukuskena kokuzula kwe-Wi-Fi okususelwa kunani ledatha yethrafikhi ekhona ekusebenzisaneni"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Amasayizi weloga ngebhafa"</string>
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Khetha amasayizi weloga ngebhafa ngayinye yelogu"</string>
@@ -325,21 +320,16 @@
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="4400068916452346544">"Cishe ngu-<xliff:g id="TIME">%1$s</xliff:g> osele"</string>
<string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> esisele"</string>
- <!-- no translation found for power_discharging_duration (2843747179907396142) -->
- <skip />
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cishe ngu-<xliff:g id="TIME">%2$s</xliff:g> osele"</string>
<string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration (4676999980973411875) -->
- <skip />
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele"</string>
<string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
- <skip />
+ <string name="power_charging_duration_ac" msgid="7341243578143555689">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele ku-AC"</string>
<string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
- <skip />
+ <string name="power_charging_duration_usb" msgid="3720632890882121805">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele nge-USB"</string>
<string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
- <skip />
+ <string name="power_charging_duration_wireless" msgid="5768338238751562058">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele kusukela kokungenantambo"</string>
<string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Akwaziwa"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string>
@@ -353,8 +343,10 @@
<string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kulawulwa umqondisi"</string>
- <string name="enabled_by_admin" msgid="2386503803463071894">"Kunikwe amandla umqondisi"</string>
- <string name="disabled_by_admin" msgid="3669999613095206948">"Ikhutshazwe umlawuli"</string>
+ <!-- no translation found for enabled_by_admin (5302986023578399263) -->
+ <skip />
+ <!-- no translation found for disabled_by_admin (8505398946020816620) -->
+ <skip />
<string name="home" msgid="3256884684164448244">"Ikhaya lezilungiselelo"</string>
<string-array name="battery_labels">
<item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 0bf1fa48879b..db3274ab478c 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -124,6 +124,8 @@
<item>aptX</item>
<item>aptX HD</item>
<item>LDAC</item>
+ <item>Enable Optional Codecs</item>
+ <item>Disable Optional Codecs</item>
</string-array>
<!-- Values for Bluetooth Audio Codec selection preference. -->
@@ -134,6 +136,8 @@
<item>2</item>
<item>3</item>
<item>4</item>
+ <item>5</item>
+ <item>6</item>
</string-array>
<!-- Summaries for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50]-->
@@ -144,6 +148,8 @@
<item>aptX</item>
<item>aptX HD</item>
<item>LDAC</item>
+ <item>Enable Optional Codecs</item>
+ <item>Disable Optional Codecs</item>
</string-array>
<!-- Titles for Bluetooth Audio Codec Sample Rate selection preference. [CHAR LIMIT=50] -->
@@ -223,6 +229,7 @@
<item>Optimized for Audio Quality (990kbps/909kbps)</item>
<item>Balanced Audio And Connection Quality (660kbps/606kbps)</item>
<item>Optimized for Connection Quality (330kbps/303kbps)</item>
+ <item>Best Effort (Adaptive Bit Rate)</item>
</string-array>
<!-- Values for Bluetooth Audio Codec LDAC Playback Quaility selection preference. -->
@@ -230,6 +237,7 @@
<item>1000</item>
<item>1001</item>
<item>1002</item>
+ <item>1003</item>
</string-array>
<!-- Summaries for Bluetooth Audio Codec LDAC Playback Quality selection preference. [CHAR LIMIT=70]-->
@@ -237,6 +245,7 @@
<item>Optimized for Audio Quality</item>
<item>Balanced Audio And Connection Quality</item>
<item>Optimized for Connection Quality</item>
+ <item>Best Effort (Adaptive Bit Rate)</item>
</string-array>
<!-- Titles for logd limit size selection preference. [CHAR LIMIT=14] -->
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index cc2dc1bb6a7d..f14d0d128e67 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -76,7 +76,7 @@
<!-- Status message of Wi-Fi when it is automatically connected by a network recommendation provider. [CHAR LIMIT=NONE] -->
<string name="connected_via_network_scorer">Automatically connected via %1$s</string>
<!-- Status message of Wi-Fi when it is automatically connected by a default network recommendation provider. [CHAR LIMIT=NONE] -->
- <string name="connected_via_network_scorer_default">Automatically connected via Network Quality Scorer</string>
+ <string name="connected_via_network_scorer_default">Automatically connected via network rating provider</string>
<!-- Status message of Wi-Fi when it is connected by Passpoint configuration. [CHAR LIMIT=NONE] -->
<string name="connected_via_passpoint">Connected via %1$s</string>
<!-- Status message of Wi-Fi when network has matching passpoint credentials. [CHAR LIMIT=NONE] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
index 4b0ab59a931c..b54d7e201c85 100644
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
@@ -106,11 +106,11 @@ public class SuggestionParser {
public SuggestionParser(
Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) {
- mContext = context;
- mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
- .parse(orderXml);
- mSharedPrefs = sharedPrefs;
- mSmartDismissControl = smartDismissControl;
+ this(
+ context,
+ sharedPrefs,
+ (List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml),
+ smartDismissControl);
}
public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
@@ -118,12 +118,15 @@ public class SuggestionParser {
}
@VisibleForTesting
- public SuggestionParser(Context context, SharedPreferences sharedPrefs) {
+ public SuggestionParser(
+ Context context,
+ SharedPreferences sharedPrefs,
+ List<SuggestionCategory> suggestionList,
+ String smartDismissControl) {
mContext = context;
- mSuggestionList = new ArrayList<SuggestionCategory>();
+ mSuggestionList = suggestionList;
mSharedPrefs = sharedPrefs;
- mSmartDismissControl = DEFAULT_SMART_DISMISS_CONTROL;
- Log.wtf(TAG, "Only use this constructor for testing");
+ mSmartDismissControl = smartDismissControl;
}
public List<Tile> getSuggestions() {
@@ -134,7 +137,19 @@ public class SuggestionParser {
List<Tile> suggestions = new ArrayList<>();
final int N = mSuggestionList.size();
for (int i = 0; i < N; i++) {
- readSuggestions(mSuggestionList.get(i), suggestions, isSmartSuggestionEnabled);
+ final SuggestionCategory category = mSuggestionList.get(i);
+ if (category.exclusive) {
+ // If suggestions from an exclusive category are present, parsing is stopped
+ // and only suggestions from that category are displayed. Note that subsequent
+ // exclusive categories are also ignored.
+ List<Tile> exclusiveSuggestions = new ArrayList<>();
+ readSuggestions(category, exclusiveSuggestions, isSmartSuggestionEnabled);
+ if (!exclusiveSuggestions.isEmpty()) {
+ return exclusiveSuggestions;
+ }
+ } else {
+ readSuggestions(category, suggestions, isSmartSuggestionEnabled);
+ }
}
return suggestions;
}
@@ -368,6 +383,7 @@ public class SuggestionParser {
public String category;
public String pkg;
public boolean multiple;
+ public boolean exclusive;
}
private static class SuggestionOrderInflater {
@@ -377,6 +393,7 @@ public class SuggestionParser {
private static final String ATTR_CATEGORY = "category";
private static final String ATTR_PACKAGE = "package";
private static final String ATTR_MULTIPLE = "multiple";
+ private static final String ATTR_EXCLUSIVE = "exclusive";
private final Context mContext;
@@ -451,6 +468,9 @@ public class SuggestionParser {
category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
+ String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE);
+ category.exclusive =
+ !TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive);
return category;
} else {
throw new IllegalArgumentException("Unknown item " + name);
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index c2ce7c9fd5de..c90daf79972b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -1582,6 +1582,21 @@ public class ApplicationsState {
}
};
+ public static final AppFilter FILTER_MOVIES = new AppFilter() {
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public boolean filterApp(AppEntry entry) {
+ boolean isMovieApp;
+ synchronized(entry) {
+ isMovieApp = entry.info.category == ApplicationInfo.CATEGORY_VIDEO;
+ }
+ return isMovieApp;
+ }
+ };
+
public static final AppFilter FILTER_OTHER_APPS = new AppFilter() {
@Override
public void init() {
@@ -1592,7 +1607,8 @@ public class ApplicationsState {
boolean isCategorized;
synchronized(entry) {
isCategorized = entry.info.category == ApplicationInfo.CATEGORY_AUDIO ||
- entry.info.category == ApplicationInfo.CATEGORY_GAME;
+ entry.info.category == ApplicationInfo.CATEGORY_GAME ||
+ entry.info.category == ApplicationInfo.CATEGORY_VIDEO;
}
return !isCategorized;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
index c7efb07ed310..5a1e603e7fa2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
@@ -23,6 +23,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.widget.RemoteViews;
import java.util.ArrayList;
@@ -84,6 +85,11 @@ public class Tile implements Parcelable {
*/
public String key;
+ /**
+ * Optional remote view which will be displayed instead of the regular title-summary item.
+ */
+ public RemoteViews remoteViews;
+
public Tile() {
// Empty
}
@@ -119,6 +125,7 @@ public class Tile implements Parcelable {
dest.writeInt(priority);
dest.writeBundle(metaData);
dest.writeString(key);
+ dest.writeParcelable(remoteViews, flags);
}
public void readFromParcel(Parcel in) {
@@ -139,6 +146,7 @@ public class Tile implements Parcelable {
priority = in.readInt();
metaData = in.readBundle();
key = in.readString();
+ remoteViews = in.readParcelable(RemoteViews.class.getClassLoader());
}
Tile(Parcel in) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index f31c09b104fd..5aeee419a6e0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -21,7 +21,6 @@ import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
@@ -35,6 +34,7 @@ import android.provider.Settings.Global;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
+import android.widget.RemoteViews;
import java.util.ArrayList;
import java.util.Collections;
@@ -153,6 +153,14 @@ public class TileUtils {
public static final String META_DATA_PREFERENCE_SUMMARY_URI =
"com.android.settings.summary_uri";
+ /**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the
+ * custom view which should be displayed for the preference. The custom view will be inflated
+ * as a remote view.
+ */
+ public static final String META_DATA_PREFERENCE_CUSTOM_VIEW =
+ "com.android.settings.custom_view";
+
public static final String SETTING_PKG = "com.android.settings";
/**
@@ -353,6 +361,7 @@ public class TileUtils {
String summary = null;
String keyHint = null;
Uri uri = null;
+ RemoteViews remoteViews = null;
// Get the activity's meta-data
try {
@@ -385,6 +394,10 @@ public class TileUtils {
keyHint = metaData.getString(META_DATA_PREFERENCE_KEYHINT);
}
}
+ if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
+ int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
+ remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
+ }
}
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
if (DEBUG) Log.d(LOG_TAG, "Couldn't find info", e);
@@ -414,6 +427,7 @@ public class TileUtils {
activityInfo.name);
// Suggest a key for this tile
tile.key = keyHint;
+ tile.remoteViews = remoteViews;
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 6764a6bb7f47..0f443d6791e3 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -101,7 +101,7 @@ public class BatteryMeterDrawableBase extends Drawable {
for (int i=0; i < N; i++) {
mColors[2 * i] = levels.getInt(i, 0);
if (colors.getType(i) == TypedValue.TYPE_ATTRIBUTE) {
- mColors[2 * i + 1] = Utils.getColorAttr(context, colors.getResourceId(i, 0));
+ mColors[2 * i + 1] = Utils.getColorAttr(context, colors.getThemeAttributeId(i, 0));
} else {
mColors[2 * i + 1] = colors.getColor(i, 0);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 0280f26e30b1..1f86f8b8d594 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -526,9 +526,13 @@ public class WifiTracker {
// the given ScanResult. This is used for showing that a given AP
// (ScanResult) is available via a Passpoint provider (provider friendly
// name).
- WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result);
- if (config != null) {
- accessPoint.update(config);
+ try {
+ WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result);
+ if (config != null) {
+ accessPoint.update(config);
+ }
+ } catch (UnsupportedOperationException e) {
+ // Passpoint not supported on the device.
}
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
index e204a3a65c72..203fdc07b85b 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
@@ -136,4 +136,18 @@ public class ApplicationsStateTest {
when(mEntry.info.isInstantApp()).thenReturn(true);
assertThat(ApplicationsState.FILTER_DISABLED.filterApp(mEntry)).isFalse();
}
+
+ @Test
+ public void testVideoFilterAcceptsCategorizedVideo() {
+ mEntry.info.category = ApplicationInfo.CATEGORY_VIDEO;
+
+ assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isTrue();
+ }
+
+ @Test
+ public void testVideosFilterRejectsNotVideo() {
+ mEntry.info.category = ApplicationInfo.CATEGORY_GAME;
+
+ assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isFalse();
+ }
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 46726f2f1438..02deb44d0cd4 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -20,9 +20,11 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -580,4 +582,40 @@ public class WifiTrackerTest {
mWorkerThread.quit();
updateScores();
}
+
+ /**
+ * Verify that tracking a Passpoint AP on a device with Passpoint disabled doesn't cause
+ * any crash.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void trackPasspointApWithPasspointDisabled() throws Exception {
+ WifiTracker tracker = createMockedWifiTracker();
+
+ // Add a Passpoint AP to the scan results.
+ List<ScanResult> results = new ArrayList<>();
+ ScanResult passpointAp = new ScanResult(
+ WifiSsid.createFromAsciiEncoded(SSID_1),
+ BSSID_1,
+ 0, // hessid
+ 0, //anqpDomainId
+ null, // osuProviders
+ "", // capabilities
+ RSSI_1,
+ 0, // frequency
+ SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
+ passpointAp.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
+ results.add(passpointAp);
+
+ // Update access point and verify UnsupportedOperationException is being caught for
+ // call to WifiManager#getMatchingWifiConfig.
+ when(mockWifiManager.getConfiguredNetworks())
+ .thenReturn(new ArrayList<WifiConfiguration>());
+ when(mockWifiManager.getScanResults()).thenReturn(results);
+ doThrow(new UnsupportedOperationException())
+ .when(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
+ tracker.forceUpdate();
+ verify(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
index 1eeafba1bf8f..0e2ce3be55eb 100644
--- a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
+++ b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
@@ -15,6 +15,8 @@
-->
<optional-steps>
+ <step category="com.android.settings.suggested.category.DEFERRED_SETUP"
+ exclusive="true" />
<step category="com.android.settings.suggested.category.LOCK_SCREEN" />
<step category="com.android.settings.suggested.category.EMAIL" />
<step category="com.android.settings.suggested.category.PARTNER_ACCOUNT"
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
index 7729dec82e4a..d5341807677d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
@@ -16,11 +16,12 @@
package com.android.settingslib;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.preference.PreferenceManager;
@@ -31,59 +32,59 @@ import com.android.settingslib.drawer.TileUtilsTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.res.ResourceLoader;
+import org.robolectric.res.builder.DefaultPackageManager;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingLibRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SuggestionParserTest {
- @Mock
- private PackageManager mPackageManager;
private Context mContext;
private SuggestionParser mSuggestionParser;
- private SuggestionParser.SuggestionCategory mSuggestioCategory;
+ private SuggestionParser.SuggestionCategory mMultipleCategory;
+ private SuggestionParser.SuggestionCategory mExclusiveCategory;
private List<Tile> mSuggestionsBeforeDismiss;
private List<Tile> mSuggestionsAfterDismiss;
private SharedPreferences mPrefs;
private Tile mSuggestion;
- private List<ResolveInfo> mInfo;
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
- when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ RuntimeEnvironment.setRobolectricPackageManager(
+ new TestPackageManager(RuntimeEnvironment.getAppResourceLoader()));
+ mContext = RuntimeEnvironment.application;
mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mSuggestion = new Tile();
mSuggestion.intent = new Intent("action");
mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
mSuggestion.metaData = new Bundle();
+ mMultipleCategory = new SuggestionParser.SuggestionCategory();
+ mMultipleCategory.category = "category1";
+ mMultipleCategory.multiple = true;
+ mExclusiveCategory = new SuggestionParser.SuggestionCategory();
+ mExclusiveCategory.category = "category2";
+ mExclusiveCategory.exclusive = true;
mSuggestionParser = new SuggestionParser(
- mContext, mPrefs, R.xml.suggestion_ordering, "0,0");
- mSuggestioCategory = new SuggestionParser.SuggestionCategory();
- mSuggestioCategory.category = "category1";
- mSuggestioCategory.multiple = true;
- mInfo = new ArrayList<>();
+ mContext, mPrefs, Arrays.asList(mMultipleCategory, mExclusiveCategory), "0,0");
+
ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1");
info1.activityInfo.packageName = "pkg";
ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1");
info2.activityInfo.packageName = "pkg2";
- mInfo.add(info1);
- mInfo.add(info2);
- when(mPackageManager.queryIntentActivitiesAsUser(
- any(Intent.class), anyInt(), anyInt())).thenReturn(mInfo);
+ ResolveInfo info3 = TileUtilsTest.newInfo(true, "category2");
+ info3.activityInfo.packageName = "pkg3";
+
+ Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
+ Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
+ RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info1);
+ RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info2);
+ RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent2, info3);
}
@Test
@@ -99,30 +100,64 @@ public class SuggestionParserTest {
@Test
public void testGetSuggestions_withoutSmartSuggestions() {
readAndDismissSuggestion(false);
- mSuggestionParser.readSuggestions(mSuggestioCategory, mSuggestionsAfterDismiss, false);
- assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
- assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(1);
+ mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
+ assertThat(mSuggestionsBeforeDismiss).hasSize(2);
+ assertThat(mSuggestionsAfterDismiss).hasSize(1);
assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
}
@Test
public void testGetSuggestions_withSmartSuggestions() {
readAndDismissSuggestion(true);
- assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
- assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(2);
+ assertThat(mSuggestionsBeforeDismiss).hasSize(2);
+ assertThat(mSuggestionsAfterDismiss).hasSize(2);
assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
}
+ @Test
+ public void testGetSuggestion_exclusiveNotAvailable() {
+ RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
+ new Intent(Intent.ACTION_MAIN).addCategory("category2"),
+ "pkg3");
+
+ // If exclusive item is not available, the other categories should be shown
+ final List<Tile> suggestions = mSuggestionParser.getSuggestions();
+ assertThat(suggestions).hasSize(2);
+ assertThat(suggestions.get(0).category).isEqualTo("category1");
+ assertThat(suggestions.get(1).category).isEqualTo("category1");
+ }
+
+ @Test
+ public void testGetSuggestions_exclusive() {
+ final List<Tile> suggestions = mSuggestionParser.getSuggestions();
+ assertThat(suggestions).hasSize(1);
+ assertThat(suggestions.get(0).category).isEqualTo("category2");
+ }
+
private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
- mSuggestionsBeforeDismiss = new ArrayList<Tile>();
- mSuggestionsAfterDismiss = new ArrayList<Tile>();
+ mSuggestionsBeforeDismiss = new ArrayList<>();
+ mSuggestionsAfterDismiss = new ArrayList<>();
mSuggestionParser.readSuggestions(
- mSuggestioCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
- if (mSuggestionParser.dismissSuggestion(
- mSuggestionsBeforeDismiss.get(0), isSmartSuggestionEnabled)) {
- mInfo.remove(0);
+ mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
+ final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
+ if (mSuggestionParser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) {
+ RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
+ new Intent(Intent.ACTION_MAIN).addCategory(suggestion.category),
+ suggestion.intent.getComponent().getPackageName());
}
mSuggestionParser.readSuggestions(
- mSuggestioCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
+ mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
+ }
+
+ private static class TestPackageManager extends DefaultPackageManager {
+
+ TestPackageManager(ResourceLoader appResourceLoader) {
+ super(appResourceLoader);
+ }
+
+ @Override
+ public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
+ return super.queryIntentActivities(intent, flags);
+ }
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 2d3c4a786f5c..1788666ea842 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -16,11 +16,22 @@
package com.android.settingslib.drawer;
-import android.app.ActivityManager;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
-import android.content.IContentProvider;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -38,36 +49,26 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Pair;
+import com.android.settingslib.R;
import com.android.settingslib.SuggestionParser;
import com.android.settingslib.TestConfig;
-import com.android.settingslib.drawer.TileUtilsTest;
-import static org.mockito.Mockito.atLeastOnce;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.shadows.ShadowApplication;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-import org.mockito.ArgumentCaptor;
-
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -179,7 +180,11 @@ public class TileUtilsTest {
false /* checkCategory */);
assertThat(outTiles.size()).isEqualTo(1);
- SuggestionParser parser = new SuggestionParser(mContext, null);
+ SuggestionParser parser = new SuggestionParser(
+ mContext,
+ null,
+ Collections.emptyList(),
+ "0,10");
parser.filterSuggestions(outTiles, 0, false);
assertThat(outTiles.size()).isEqualTo(0);
}
@@ -289,6 +294,30 @@ public class TileUtilsTest {
assertThat(outTiles.size()).isEqualTo(1);
}
+ @Test
+ public void getTilesForIntent_shouldShowRemoteViewIfSpecified() {
+ Intent intent = new Intent();
+ Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+ List<Tile> outTiles = new ArrayList<>();
+ List<ResolveInfo> info = new ArrayList<>();
+ ResolveInfo resolveInfo = newInfo(true, null /* category */);
+ resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+ R.layout.user_preference);
+ info.add(resolveInfo);
+
+ when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+ .thenReturn(info);
+
+ TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+ null /* defaultCategory */, outTiles, false /* usePriority */,
+ false /* checkCategory */);
+
+ assertThat(outTiles.size()).isEqualTo(1);
+ Tile tile = outTiles.get(0);
+ assertThat(tile.remoteViews).isNotNull();
+ assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+ }
+
public static ResolveInfo newInfo(boolean systemApp, String category) {
return newInfo(systemApp, category, null);
}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 14bb02d9b376..a8629f84025b 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -51,7 +51,7 @@
<bool name="def_wifi_on">false</bool>
<!-- 0 == never, 1 == only when plugged in, 2 == always -->
<integer name="def_wifi_sleep_policy">2</integer>
- <bool name="def_wifi_wakeup_enabled">false</bool>
+ <bool name="def_wifi_wakeup_enabled">true</bool>
<bool name="def_networks_available_notification_on">true</bool>
<bool name="def_backup_enabled">false</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 1a752f924425..0d0ddf2046a7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2798,7 +2798,7 @@ public class SettingsProvider extends ContentProvider {
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 142;
+ private static final int SETTINGS_VERSION = 143;
private final int mUserId;
@@ -3343,10 +3343,30 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 142;
}
+ if (currentVersion == 142) {
+ // Version 142: Set a default value for Wi-Fi wakeup feature.
+ if (userId == UserHandle.USER_SYSTEM) {
+ final SettingsState globalSettings = getGlobalSettingsLocked();
+ Setting currentSetting = globalSettings.getSettingLocked(
+ Settings.Global.WIFI_WAKEUP_ENABLED);
+ if (currentSetting.isNull()) {
+ globalSettings.insertSettingLocked(
+ Settings.Global.WIFI_WAKEUP_ENABLED,
+ getContext().getResources().getBoolean(
+ R.bool.def_wifi_wakeup_enabled) ? "1" : "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ }
+
+ currentVersion = 143;
+ }
+
if (currentVersion != newVersion) {
Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
+ newVersion + " left it at "
- + currentVersion + " instead; this is probably a bug", new Throwable());
+ + currentVersion +
+ " instead; this is probably a bug. Did you update SETTINGS_VERSION?",
+ new Throwable());
if (DEBUG) {
throw new RuntimeException("db upgrade error");
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 6bfab78fcd62..2519e029dbd9 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -113,6 +113,7 @@
<uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+ <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
<uses-permission android:name="android.permission.MANAGE_AUTO_FILL" />
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 1ebfbad6d206..635c96f23778 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -38,7 +38,6 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \
android-support-v17-leanback
LOCAL_STATIC_JAVA_LIBRARIES := \
- framework-protos \
SystemUI-tags \
SystemUI-proto
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index e4d71b65ed6a..1147f16f5522 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -181,7 +181,7 @@
<uses-permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" />
<!-- to control accessibility volume -->
- <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
+ <uses-permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" />
<application
android:name=".SystemUIApplication"
diff --git a/packages/SystemUI/plugin/Android.mk b/packages/SystemUI/plugin/Android.mk
index 05ee6b23c4b7..e22dddb6d565 100644
--- a/packages/SystemUI/plugin/Android.mk
+++ b/packages/SystemUI/plugin/Android.mk
@@ -36,4 +36,6 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := SystemUIPluginLib
+LOCAL_PROGUARD_ENABLED := disabled
+
include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java
index 152dbc5e06be..1bfa567b6630 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java
@@ -29,8 +29,8 @@ public abstract class PluginFragment extends Fragment implements Plugin {
}
@Override
- public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
- return super.getLayoutInflater(savedInstanceState).cloneInContext(getContext());
+ public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
+ return super.onGetLayoutInflater(savedInstanceState).cloneInContext(getContext());
}
@Override
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 25d52263957b..1c087b374a2b 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -43,6 +43,8 @@
android:alpha="0"
android:background="@color/qs_detail_progress_track"
android:src="@drawable/indeterminate_anim"
+ android:scaleType="fitXY"
+ android:translationY="16dp"
/>
<com.android.systemui.qs.NonInterceptingScrollView
@@ -57,6 +59,6 @@
android:layout_height="match_parent"/>
</com.android.systemui.qs.NonInterceptingScrollView>
- <include layout="@layout/qs_detail_buttons"/>
+ <include layout="@layout/qs_detail_buttons" />
</com.android.systemui.qs.QSDetail>
diff --git a/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml b/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml
index d2daa89ff03b..a1c1e5bd32c7 100644
--- a/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml
+++ b/packages/SystemUI/res/layout/recents_incompatible_app_overlay.xml
@@ -26,6 +26,6 @@
android:layout_gravity="center"
android:drawableTop="@drawable/recents_info_light"
android:drawablePadding="8dp"
- android:text="@string/recents_incompatible_app_message"
+ android:text="@string/dock_non_resizeble_failed_to_dock_text"
android:textColor="@android:color/white" />
</FrameLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 64cac3c001d1..6a7547050ba5 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -106,7 +106,7 @@
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
- wifi,cell,bt,dnd,flashlight,rotation,battery,airplane
+ wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast
</string>
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
@@ -209,9 +209,12 @@
<!-- Set to true to enable the user switcher on the keyguard. -->
<bool name="config_keyguardUserSwitcher">false</bool>
- <!-- Doze: does this device support STATE_DOZE and STATE_DOZE_SUSPEND? -->
+ <!-- Doze: does this device support STATE_DOZE? -->
<bool name="doze_display_state_supported">false</bool>
+ <!-- Doze: does this device support STATE_DOZE_SUSPEND? -->
+ <bool name="doze_suspend_display_state_supported">false</bool>
+
<!-- Doze: should the significant motion sensor be used as a pulse signal? -->
<bool name="doze_pulse_on_significant_motion">false</bool>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5b20716fa41f..a2ec804f08ad 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -789,8 +789,6 @@
<string name="recents_launch_disabled_message"><xliff:g id="app" example="Calendar">%s</xliff:g> is disabled in safe-mode.</string>
<!-- Recents: Stack action button string. [CHAR LIMIT=NONE] -->
<string name="recents_stack_action_button_label">Clear all</string>
- <!-- Recents: Incompatible task message. [CHAR LIMIT=NONE] -->
- <string name="recents_incompatible_app_message">App doesn\'t support split screen</string>
<!-- Recents: Hint text that shows on the drop targets to start multiwindow. [CHAR LIMIT=NONE] -->
<string name="recents_drag_hint_message">Drag here to use split screen</string>
@@ -1869,15 +1867,21 @@
<!-- Title of menu shown over picture-in-picture. Used for accessibility. -->
<string name="pip_menu_title">Picture in picture menu</string>
- <!-- User visible notification channel name for the PiP BTW notification. [CHAR LIMIT=NONE] -->
- <string name="pip_notification_channel_name">Picture-in-picture</string>
-
<!-- PiP BTW notification title. [CHAR LIMIT=50] -->
<string name="pip_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is in picture-in-picture</string>
<!-- PiP BTW notification description. [CHAR LIMIT=NONE] -->
<string name="pip_notification_message">If you don’t want <xliff:g id="name" example="Google Maps">%s</xliff:g> to use this feature, tap to open settings and turn it off.</string>
+ <!-- PiP section of the tuner. [CHAR LIMIT=NONE] -->
+ <string name="picture_in_picture" translatable="false">Picture-in-Picture</string>
+
+ <!-- PiP minimize title. [CHAR LIMIT=NONE]-->
+ <string name="pip_minimize_title" translatable="false">Minimize</string>
+
+ <!-- PiP minimize description. [CHAR LIMIT=NONE] -->
+ <string name="pip_minimize_description" translatable="false">Drag or fling the PIP to the edges of the screen to minimize it.</string>
+
<!-- Tuner string -->
<string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
<!-- Tuner string -->
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index bc3edd58f252..a685c794c5d6 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -122,6 +122,18 @@
</PreferenceScreen>
<PreferenceScreen
+ android:key="picture_in_picture"
+ android:title="@string/picture_in_picture">
+
+ <com.android.systemui.tuner.TunerSwitch
+ android:key="pip_minimize"
+ android:title="@string/pip_minimize_title"
+ android:summary="@string/pip_minimize_description"
+ sysui:defValue="false" />
+
+ </PreferenceScreen>
+
+ <PreferenceScreen
android:key="doze"
android:title="@string/tuner_doze">
@@ -133,7 +145,7 @@
<com.android.systemui.tuner.TunerSwitch
android:key="doze_sensors_wake_up_fully"
android:title="@string/tuner_doze_sensors_wake_up_fully"
- sysui:defValue="true" />
+ sysui:defValue="false" />
</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index d058e7837423..79190cbb129f 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -24,6 +24,7 @@ import android.util.ArrayMap;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.NightDisplayController;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.Preconditions;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.assist.AssistManager;
@@ -257,6 +258,8 @@ public class Dependency extends SystemUI {
mProviders.put(VolumeDialogController.class, () ->
new VolumeDialogControllerImpl(mContext));
+ mProviders.put(MetricsLogger.class, () -> new MetricsLogger());
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 9a4179f4fef5..6571294cdb92 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -405,17 +405,17 @@ public class ImageWallpaper extends WallpaperService {
}
} else {
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
+ if (FIXED_SIZED_SURFACE) {
+ // If the surface is fixed-size, we should only need to
+ // draw it once and then we'll let the window manager
+ // position it appropriately. As such, we no longer needed
+ // the loaded bitmap. Yay!
+ // hw-accelerated renderer retains bitmap for faster rotation
+ unloadWallpaper(false /* forgetSize */);
+ }
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- if (FIXED_SIZED_SURFACE && !mIsHwAccelerated) {
- // If the surface is fixed-size, we should only need to
- // draw it once and then we'll let the window manager
- // position it appropriately. As such, we no longer needed
- // the loaded bitmap. Yay!
- // hw-accelerated renderer retains bitmap for faster rotation
- unloadWallpaper(false /* forgetSize */);
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index ba8e54aac759..4d8323bf3fbf 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -50,7 +50,8 @@ public class DozeFactory {
WakeLock wakeLock = WakeLock.createPartial(context, "Doze");
DozeMachine machine = new DozeMachine(
- DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params),
+ DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(
+ DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params), params),
config,
wakeLock);
machine.setParts(new DozeMachine.Part[]{
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index f27521e20bbc..f4984109ed10 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -87,8 +87,9 @@ public class DozeMachine {
case DOZE:
return Display.STATE_OFF;
case DOZE_PULSING:
+ return Display.STATE_DOZE;
case DOZE_AOD:
- return Display.STATE_DOZE; // TODO: use STATE_ON if appropriate.
+ return Display.STATE_DOZE_SUSPEND;
default:
return Display.STATE_UNKNOWN;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
new file mode 100644
index 000000000000..1e067974e3cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.doze;
+
+import android.support.annotation.VisibleForTesting;
+import android.view.Display;
+
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+/**
+ * Prevents usage of doze screen states on devices that don't support them.
+ */
+public class DozeSuspendScreenStatePreventingAdapter implements DozeMachine.Service {
+
+ private final DozeMachine.Service mInner;
+
+ @VisibleForTesting
+ DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner) {
+ mInner = inner;
+ }
+
+ @Override
+ public void finish() {
+ mInner.finish();
+ }
+
+ @Override
+ public void setDozeScreenState(int state) {
+ if (state == Display.STATE_DOZE_SUSPEND) {
+ state = Display.STATE_DOZE;
+ }
+ mInner.setDozeScreenState(state);
+ }
+
+ @Override
+ public void requestWakeUp() {
+ mInner.requestWakeUp();
+ }
+
+ /**
+ * If the device supports the doze display state, return {@code inner}. Otherwise
+ * return a new instance of {@link DozeSuspendScreenStatePreventingAdapter} wrapping {@code inner}.
+ */
+ public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner,
+ DozeParameters params) {
+ return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner) : inner;
+ }
+
+ private static boolean isNeeded(DozeParameters params) {
+ return !params.getDozeSuspendDisplayStateSupported();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 6cda0766663d..87f8ddb7f2f2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -172,7 +172,8 @@ public class PipManager implements BasePipManager {
mInputConsumerController);
mTouchHandler = new PipTouchHandler(context, mActivityManager, mMenuController,
mInputConsumerController);
- mNotificationController = new PipNotificationController(context, mActivityManager);
+ mNotificationController = new PipNotificationController(context, mActivityManager,
+ mTouchHandler.getMotionHelper());
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index ebda2e8a7f57..ec80745f8d26 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -45,14 +45,12 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -61,6 +59,7 @@ import com.android.systemui.Interpolators;
import com.android.systemui.R;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -128,8 +127,9 @@ public class PipMenuActivity extends Activity {
break;
case MESSAGE_UPDATE_ACTIONS: {
final Bundle data = (Bundle) msg.obj;
- setActions(data.getParcelable(EXTRA_STACK_BOUNDS),
- ((ParceledListSlice) data.getParcelable(EXTRA_ACTIONS)).getList());
+ final ParceledListSlice actions = data.getParcelable(EXTRA_ACTIONS);
+ setActions(data.getParcelable(EXTRA_STACK_BOUNDS), actions != null
+ ? actions.getList() : Collections.EMPTY_LIST);
break;
}
case MESSAGE_UPDATE_DISMISS_FRACTION: {
@@ -260,6 +260,7 @@ public class PipMenuActivity extends Activity {
}
notifyMenuVisibility(true);
updateExpandButtonFromBounds(stackBounds, movementBounds);
+ setDecorViewVisibility(true);
mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
mMenuContainer.getAlpha(), 1f);
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
@@ -300,9 +301,7 @@ public class PipMenuActivity extends Activity {
if (animationFinishedRunnable != null) {
animationFinishedRunnable.run();
}
- if (getSystemService(AccessibilityManager.class).isEnabled()) {
- finish();
- }
+ setDecorViewVisibility(false);
}
});
mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
@@ -411,6 +410,7 @@ public class PipMenuActivity extends Activity {
}
private void updateDismissFraction(float fraction) {
+ setDecorViewVisibility(true);
int alpha;
if (mMenuVisible) {
mMenuContainer.setAlpha(1-fraction);
@@ -497,4 +497,16 @@ public class PipMenuActivity extends Activity {
v.removeCallbacks(mFinishRunnable);
v.postDelayed(mFinishRunnable, delay);
}
+
+ /**
+ * Sets the visibility of the root view of the window to disable drawing and touches for the
+ * activity. This differs from {@link Activity#setVisible(boolean)} in that it does not set
+ * the internal mVisibleFromClient state.
+ */
+ private void setDecorViewVisibility(boolean visible) {
+ final View decorView = getWindow().getDecorView();
+ if (decorView != null) {
+ decorView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java
index bdd6b65026f0..db83b8b918a4 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipNotificationController.java
@@ -16,15 +16,17 @@
package com.android.systemui.pip.phone;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.provider.Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS;
+import android.app.AppOpsManager;
+import android.app.AppOpsManager.OnOpChangedListener;
import android.app.IActivityManager;
import android.app.Notification;
-import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -40,6 +42,7 @@ import android.util.Log;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
+import com.android.systemui.util.NotificationChannels;
/**
* Manages the BTW notification that shows whenever an activity enters or leaves picture-in-picture.
@@ -47,64 +50,79 @@ import com.android.systemui.SystemUI;
public class PipNotificationController {
private static final String TAG = PipNotificationController.class.getSimpleName();
- private static final String CHANNEL_ID = PipNotificationController.class.getName();
- private static final int BTW_NOTIFICATION_ID = 0;
+ private static final String NOTIFICATION_TAG = PipNotificationController.class.getName();
+ private static final int NOTIFICATION_ID = 0;
private Context mContext;
private IActivityManager mActivityManager;
+ private AppOpsManager mAppOpsManager;
private NotificationManager mNotificationManager;
- public PipNotificationController(Context context, IActivityManager activityManager) {
+ private PipMotionHelper mMotionHelper;
+
+ private AppOpsManager.OnOpChangedListener mAppOpsChangedListener = new OnOpChangedListener() {
+ @Override
+ public void onOpChanged(String op, String packageName) {
+ try {
+ // Dismiss the PiP once the user disables the app ops setting for that package
+ final ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
+ packageName, 0);
+ if (mAppOpsManager.checkOpNoThrow(OP_PICTURE_IN_PICTURE, appInfo.uid, packageName)
+ != MODE_ALLOWED) {
+ mMotionHelper.dismissPip();
+ }
+ } catch (NameNotFoundException e) {
+ // Unregister the listener if the package can't be found
+ unregisterAppOpsListener();
+ }
+ }
+ };
+
+ public PipNotificationController(Context context, IActivityManager activityManager,
+ PipMotionHelper motionHelper) {
mContext = context;
mActivityManager = activityManager;
+ mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mNotificationManager = NotificationManager.from(context);
- createNotificationChannel();
+ mMotionHelper = motionHelper;
}
public void onActivityPinned(String packageName) {
// Clear any existing notification
- mNotificationManager.cancel(CHANNEL_ID, BTW_NOTIFICATION_ID);
+ mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
// Build a new notification
- final Notification.Builder builder = new Notification.Builder(mContext, CHANNEL_ID)
- .setLocalOnly(true)
- .setOngoing(true)
- .setSmallIcon(R.drawable.pip_notification_icon)
- .setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color));
+ final Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.GENERAL)
+ .setLocalOnly(true)
+ .setOngoing(true)
+ .setSmallIcon(R.drawable.pip_notification_icon)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
if (updateNotificationForApp(builder, packageName)) {
SystemUI.overrideNotificationAppName(mContext, builder);
// Show the new notification
- mNotificationManager.notify(CHANNEL_ID, BTW_NOTIFICATION_ID, builder.build());
+ mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build());
}
+
+ // Register for changes to the app ops setting for this package while it is in PiP
+ registerAppOpsListener(packageName);
}
public void onActivityUnpinned() {
+ // Unregister for changes to the previously PiP'ed package
+ unregisterAppOpsListener();
+
ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext, mActivityManager);
if (topPipActivity != null) {
onActivityPinned(topPipActivity.getPackageName());
} else {
- mNotificationManager.cancel(CHANNEL_ID, BTW_NOTIFICATION_ID);
+ mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
}
}
/**
- * Create the notification channel for the PiP BTW notifications if necessary.
- */
- private NotificationChannel createNotificationChannel() {
- NotificationChannel channel = mNotificationManager.getNotificationChannel(CHANNEL_ID);
- if (channel == null) {
- channel = new NotificationChannel(CHANNEL_ID,
- mContext.getString(R.string.pip_notification_channel_name), IMPORTANCE_MIN);
- channel.enableLights(false);
- channel.enableVibration(false);
- mNotificationManager.createNotificationChannel(channel);
- }
- return channel;
- }
-
- /**
* Updates the notification builder with app-specific information, returning whether it was
* successful.
*/
@@ -139,4 +157,13 @@ public class PipNotificationController {
}
return false;
}
+
+ private void registerAppOpsListener(String packageName) {
+ mAppOpsManager.startWatchingMode(OP_PICTURE_IN_PICTURE, packageName,
+ mAppOpsChangedListener);
+ }
+
+ private void unregisterAppOpsListener() {
+ mAppOpsManager.stopWatchingMode(mAppOpsChangedListener);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index f70d5b41ac3e..a0f491f3ba34 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -37,8 +37,10 @@ import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
@@ -46,9 +48,11 @@ import java.io.PrintWriter;
* Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
* the PIP.
*/
-public class PipTouchHandler {
+public class PipTouchHandler implements TunerService.Tunable {
private static final String TAG = "PipTouchHandler";
+ private static final String TUNER_KEY_MINIMIZE = "pip_minimize";
+
// These values are used for metrics and should never change
private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0;
private static final int METRIC_VALUE_DISMISSED_BY_DRAG = 1;
@@ -97,6 +101,9 @@ public class PipTouchHandler {
}
};
+ // Allow the PIP to be dragged to the edge of the screen to be minimized.
+ private boolean mEnableMinimize = false;
+
// Behaviour states
private boolean mIsMenuVisible;
private boolean mIsMinimized;
@@ -104,6 +111,8 @@ public class PipTouchHandler {
private int mImeHeight;
private float mSavedSnapFraction = -1f;
private boolean mSendingHoverAccessibilityEvents;
+ private boolean mMovementWithinMinimize;
+ private boolean mMovementWithinDismiss;
// Touch state
private final PipTouchState mTouchState;
@@ -167,6 +176,9 @@ public class PipTouchHandler {
mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize(
R.dimen.pip_expanded_shortest_edge_size);
+ // Register any tuner settings changes
+ Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_MINIMIZE);
+
// Register the listener for input consumer touch events
inputConsumerController.setTouchListener(this::handleTouchEvent);
inputConsumerController.setRegistrationListener(this::onRegistrationChanged);
@@ -187,6 +199,20 @@ public class PipTouchHandler {
}
}
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ if (newValue == null) {
+ // Reset back to default
+ mEnableMinimize = false;
+ return;
+ }
+ switch (key) {
+ case TUNER_KEY_MINIMIZE:
+ mEnableMinimize = Integer.parseInt(newValue) != 0;
+ break;
+ }
+ }
+
public void onConfigurationChanged() {
mMotionHelper.onConfigurationChanged();
mMotionHelper.synchronizePinnedStackBounds();
@@ -366,6 +392,9 @@ public class PipTouchHandler {
* Sets the minimized state.
*/
void setMinimizedStateInternal(boolean isMinimized) {
+ if (!mEnableMinimize) {
+ return;
+ }
setMinimizedState(isMinimized, false /* fromController */);
}
@@ -373,6 +402,9 @@ public class PipTouchHandler {
* Sets the minimized state.
*/
void setMinimizedState(boolean isMinimized, boolean fromController) {
+ if (!mEnableMinimize) {
+ return;
+ }
if (mIsMinimized != isMinimized) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MINIMIZED,
isMinimized);
@@ -435,6 +467,8 @@ public class PipTouchHandler {
* Gesture controlling normal movement of the PIP.
*/
private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
+ // Whether the PiP was on the left side of the screen at the start of the gesture
+ private boolean mStartedOnLeft;
@Override
public void onDown(PipTouchState touchState) {
@@ -442,6 +476,10 @@ public class PipTouchHandler {
return;
}
+ mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
+ mMovementWithinMinimize = true;
+ mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
+
// If the menu is still visible, and we aren't minimized, then just poke the menu
// so that it will timeout after the user stops touching it
if (mMenuController.isMenuVisible() && !mIsMinimized) {
@@ -475,7 +513,7 @@ public class PipTouchHandler {
final PointF lastDelta = touchState.getLastTouchDelta();
float left = mTmpBounds.left + lastDelta.x;
float top = mTmpBounds.top + lastDelta.y;
- if (!touchState.allowDraggingOffscreen()) {
+ if (!touchState.allowDraggingOffscreen() || !mEnableMinimize) {
left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left));
}
if (ENABLE_DISMISS_DRAG_TO_EDGE) {
@@ -493,6 +531,18 @@ public class PipTouchHandler {
if (ENABLE_DISMISS_DRAG_TO_EDGE) {
updateDismissFraction();
}
+
+ final PointF curPos = touchState.getLastTouchPosition();
+ if (mMovementWithinMinimize) {
+ // Track if movement remains near starting edge to identify swipes to minimize
+ mMovementWithinMinimize = mStartedOnLeft
+ ? curPos.x <= mMovementBounds.left + mTmpBounds.width()
+ : curPos.x >= mMovementBounds.right;
+ }
+ if (mMovementWithinDismiss) {
+ // Track if movement remains near the bottom edge to identify swipe to dismiss
+ mMovementWithinDismiss = curPos.y >= mMovementBounds.bottom;
+ }
return true;
}
return false;
@@ -526,8 +576,15 @@ public class PipTouchHandler {
}
if (touchState.isDragging()) {
- final boolean onLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
- boolean isFlingToBot = isFlingTowardsEdge(touchState, 4 /* bottom */);
+ final PointF vel = touchState.getVelocity();
+ final float velocity = PointF.length(vel.x, vel.y);
+ final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond();
+ final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y);
+ final boolean isFlingToBot = isFling
+ && !isHorizontal && mMovementWithinDismiss && vel.y > 0;
+ final boolean isFlingToEdge = isFling && isHorizontal && mMovementWithinMinimize
+ && (mStartedOnLeft ? vel.x < 0 : vel.x > 0);
+
if (ENABLE_DISMISS_DRAG_TO_EDGE
&& (mMotionHelper.shouldDismissPip() || isFlingToBot)) {
mMotionHelper.animateDragToEdgeDismiss(mMotionHelper.getBounds(),
@@ -536,8 +593,8 @@ public class PipTouchHandler {
MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
METRIC_VALUE_DISMISSED_BY_DRAG);
return true;
- } else if (!mIsMinimized && (mMotionHelper.shouldMinimizePip()
- || isFlingTowardsEdge(touchState, onLeft ? 2 : 3))) {
+ } else if (mEnableMinimize &&
+ !mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) {
// Pip should be minimized
setMinimizedStateInternal(true);
if (mMenuController.isMenuVisible()) {
@@ -563,9 +620,7 @@ public class PipTouchHandler {
mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
}
- final PointF vel = mTouchState.getVelocity();
- final float velocity = PointF.length(vel.x, vel.y);
- if (velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+ if (isFling) {
mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds,
mUpdateScrimListener);
} else {
@@ -585,42 +640,6 @@ public class PipTouchHandler {
};
/**
- * @return whether the gesture ending in {@param vel} is fast enough to be a fling and towards
- * the provided {@param edge} where:
- *
- * 1 = top
- * 2 = left
- * 3 = right
- * 4 = bottom
- */
- private boolean isFlingTowardsEdge(PipTouchState touchState, int edge) {
- final PointF vel = touchState.getVelocity();
- final PointF downPos = touchState.getDownTouchPosition();
- final Rect bounds = mMotionHelper.getBounds();
- final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y);
- final boolean isFling =
- PointF.length(vel.x, vel.y) > mFlingAnimationUtils.getMinVelocityPxPerSecond();
- if (!isFling) {
- return false;
- }
- switch (edge) {
- case 1: // top
- return !isHorizontal && vel.y < 0
- && downPos.y <= mMovementBounds.top + bounds.height();
- case 2: // left
- return isHorizontal && vel.x < 0
- && downPos.x <= mMovementBounds.left + bounds.width();
- case 3: // right
- return isHorizontal && vel.x > 0
- && downPos.x >= mMovementBounds.right;
- case 4: // bottom
- return !isHorizontal && vel.y > 0
- && downPos.y >= mMovementBounds.bottom;
- }
- return false;
- }
-
- /**
* Updates the current movement bounds based on whether the menu is currently visible.
*/
private void updateMovementBounds(boolean isExpanded) {
@@ -643,6 +662,7 @@ public class PipTouchHandler {
pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
pw.println(innerPrefix + "mEnableDragToDismiss=" + ENABLE_DISMISS_DRAG_TO_TARGET);
+ pw.println(innerPrefix + "mEnableMinimize=" + mEnableMinimize);
mSnapAlgorithm.dump(pw, innerPrefix);
mTouchState.dump(pw, innerPrefix);
mMotionHelper.dump(pw, innerPrefix);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index a30b03b9a411..6b507645e4d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -230,12 +230,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
firstPageBuilder.addFloat(brightness, "translationY", heightDiff, 0);
mBrightnessAnimator = new TouchAnimator.Builder()
.addFloat(brightness, "alpha", 0, 1)
- .addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1)
- .addFloat(mQsPanel.getDivider(), "alpha", 0, 1)
.setStartDelay(.5f)
.build();
- mAllViews.add(mQsPanel.getPageIndicator());
- mAllViews.add(mQsPanel.getDivider());
mAllViews.add(brightness);
} else {
mBrightnessAnimator = null;
@@ -247,7 +243,11 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
mFirstPageDelayedAnimator = new TouchAnimator.Builder()
.setStartDelay(EXPANDED_TILE_DELAY)
.addFloat(tileLayout, "alpha", 0, 1)
+ .addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1)
+ .addFloat(mQsPanel.getDivider(), "alpha", 0, 1)
.addFloat(mQsPanel.getFooter().getView(), "alpha", 0, 1).build();
+ mAllViews.add(mQsPanel.getPageIndicator());
+ mAllViews.add(mQsPanel.getDivider());
mAllViews.add(mQsPanel.getFooter().getView());
float px = 0;
float py = 1;
@@ -264,6 +264,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
}
mNonfirstPageAnimator = new TouchAnimator.Builder()
.addFloat(mQuickQsPanel, "alpha", 1, 0)
+ .addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1)
+ .addFloat(mQsPanel.getDivider(), "alpha", 0, 1)
.setListener(mNonFirstPageListener)
.setEndDelay(.5f)
.build();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 1709718b1301..9efe224ff52f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -14,6 +14,8 @@
package com.android.systemui.qs;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_MORE_SETTINGS;
+
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
@@ -197,7 +199,7 @@ public class QSDetail extends LinearLayout {
mDetailContent.removeAllViews();
mDetailContent.addView(detailView);
mDetailViews.put(viewCacheIndex, detailView);
- MetricsLogger.visible(mContext, adapter.getMetricsCategory());
+ Dependency.get(MetricsLogger.class).visible(adapter.getMetricsCategory());
announceForAccessibility(mContext.getString(
R.string.accessibility_quick_settings_detail,
adapter.getTitle()));
@@ -206,7 +208,7 @@ public class QSDetail extends LinearLayout {
setVisibility(View.VISIBLE);
} else {
if (mDetailAdapter != null) {
- MetricsLogger.hidden(mContext, mDetailAdapter.getMetricsCategory());
+ Dependency.get(MetricsLogger.class).hidden(mDetailAdapter.getMetricsCategory());
}
mClosingDetail = true;
mDetailAdapter = null;
@@ -238,8 +240,12 @@ public class QSDetail extends LinearLayout {
protected void setupDetailFooter(DetailAdapter adapter) {
final Intent settingsIntent = adapter.getSettingsIntent();
mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
- mDetailSettingsButton.setOnClickListener(v -> Dependency.get(ActivityStarter.class)
- .postStartActivityDismissingKeyguard(settingsIntent, 0));
+ mDetailSettingsButton.setOnClickListener(v -> {
+ Dependency.get(MetricsLogger.class).action(ACTION_QS_MORE_SETTINGS,
+ mDetailAdapter.getMetricsCategory());
+ Dependency.get(ActivityStarter.class)
+ .postStartActivityDismissingKeyguard(settingsIntent, 0);
+ });
}
protected void setupDetailHeader(final DetailAdapter adapter) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 2202b5865def..d51fe8a2f690 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_DATE;
+
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
@@ -49,6 +51,7 @@ import com.android.systemui.qs.TouchAnimator.Builder;
import com.android.systemui.statusbar.phone.ExpandableIndicator;
import com.android.systemui.statusbar.phone.MultiUserSwitch;
import com.android.systemui.statusbar.phone.SettingsButton;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -160,11 +163,10 @@ public class QSFooter extends LinearLayout implements
final Builder builder = new Builder()
.addFloat(mSettingsContainer, "translationX", -(remaining - defSpace), 0)
.addFloat(mSettingsButton, "rotation", -120, 0)
- .addFloat(mAlarmStatus, "alpha", 0, 1)
- .addFloat(mAlarmStatus, "translationX", 0, -mDate.getWidth())
- .addFloat(mAlarmStatusCollapsed, "translationX", 0, -mDate.getWidth());
+ .addFloat(mAlarmStatus, "alpha", 0, 1);
if (mAlarmShowing) {
- builder.addFloat(mDate, "alpha", 1, 0);
+ builder.addFloat(mDate, "alpha", 1, 0)
+ .addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth());
}
mAnimator = builder.build();
setExpansion(mExpansionAmount);
@@ -336,6 +338,11 @@ public class QSFooter extends LinearLayout implements
@Override
public void onClick(View v) {
if (v == mSettingsButton) {
+ if (!Dependency.get(DeviceProvisionedController.class).isCurrentUserSetup()) {
+ // If user isn't setup just unlock the device and dump them back at SUW.
+ mActivityStarter.postQSRunnableDismissingKeyguard(() -> { });
+ return;
+ }
MetricsLogger.action(mContext,
mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
: MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH);
@@ -358,6 +365,8 @@ public class QSFooter extends LinearLayout implements
startSettingsActivity();
}
} else if (v == mDateTimeGroup) {
+ Dependency.get(MetricsLogger.class).action(ACTION_QS_DATE,
+ mNextAlarm != null);
if (mNextAlarm != null) {
PendingIntent showIntent = mNextAlarm.getShowIntent();
mActivityStarter.startPendingIntentDismissingKeyguard(showIntent);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 63563b2e31ed..406f107f9872 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -21,6 +21,7 @@ import android.app.Fragment;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,6 +40,8 @@ import com.android.systemui.statusbar.stack.StackStateAnimator;
public class QSFragment extends Fragment implements QS {
private static final String TAG = "QS";
private static final boolean DEBUG = false;
+ private static final String EXTRA_EXPANDED = "expanded";
+ private static final String EXTRA_LISTENING = "listening";
private final Rect mQsBounds = new Rect();
private boolean mQsExpanded;
@@ -85,6 +88,35 @@ public class QSFragment extends Fragment implements QS {
mQSCustomizer = view.findViewById(R.id.qs_customize);
mQSCustomizer.setQs(this);
+ if (savedInstanceState != null) {
+ setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED));
+ setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mListening) {
+ setListening(false);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
+ outState.putBoolean(EXTRA_LISTENING, mListening);
+ }
+
+ @VisibleForTesting
+ boolean isListening() {
+ return mListening;
+ }
+
+ @VisibleForTesting
+ boolean isExpanded() {
+ return mQsExpanded;
}
@Override
@@ -221,7 +253,7 @@ public class QSFragment extends Fragment implements QS {
}
// Set bounds on the QS panel so it doesn't run over the header.
- mQsBounds.top = (int) (mHeader.getBottom() * (1 - expansion));
+ mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion));
mQsBounds.right = mQSPanel.getWidth();
mQsBounds.bottom = mQSPanel.getHeight();
mQSPanel.setClipBounds(mQsBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index 29d547cfd5d2..8596b578f030 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -32,6 +32,8 @@ public interface QSHost {
TileServices getTileServices();
void removeTile(String tileSpec);
+ int indexOf(String tileSpec);
+
interface Callback {
void onTilesChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 8298cbb7d7fe..2e6116dba7e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -59,6 +59,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
protected final View mBrightnessView;
private final H mHandler = new H();
private final View mPageIndicator;
+ private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private int mPanelPaddingBottom;
private int mBrightnessPaddingTop;
@@ -259,7 +260,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
if (!mExpanded && mTileLayout instanceof PagedTileLayout) {
((PagedTileLayout) mTileLayout).setCurrentItem(0, false);
}
- MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, mExpanded);
+ mMetricsLogger.visibility(MetricsEvent.QS_PANEL, mExpanded);
if (!mExpanded) {
closeDetail();
} else {
@@ -475,7 +476,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
int newVis = visible ? VISIBLE : INVISIBLE;
setVisibility(newVis);
if (mGridContentVisible != visible) {
- MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, newVis);
+ mMetricsLogger.visibility(MetricsEvent.QS_PANEL, newVis);
}
mGridContentVisible = visible;
}
@@ -483,7 +484,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
private void logTiles() {
for (int i = 0; i < mRecords.size(); i++) {
TileRecord tileRecord = mRecords.get(i);
- MetricsLogger.visible(mContext, tileRecord.tile.getMetricsCategory());
+ mMetricsLogger.visible(tileRecord.tile.getMetricsCategory());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 0ca115e43c07..933054138a8a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -157,6 +157,10 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory> {
return mServices;
}
+ public int indexOf(String spec) {
+ return mTileSpecs.indexOf(spec);
+ }
+
@Override
public void onTuningChanged(String key, String newValue) {
if (!TILES_SETTING.equals(key)) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index d8e554254076..596d3bc6e8f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -209,7 +209,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
for (String tile : defTiles.split(",")) {
tiles.add(tile);
}
- mTileAdapter.setTileSpecs(tiles);
+ mTileAdapter.resetTileSpecs(mHost, tiles);
}
private void setTileSpecs() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index c33d7da2d808..0a0d2ce00a1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -114,6 +114,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
mCurrentSpecs = newSpecs;
}
+ public void resetTileSpecs(QSTileHost host, List<String> specs) {
+ // Notify the host so the tiles get removed callbacks.
+ host.changeTiles(mCurrentSpecs, specs);
+ setTileSpecs(specs);
+ }
+
public void setTileSpecs(List<String> currentSpecs) {
if (currentSpecs.equals(mCurrentSpecs)) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 6f35017b893b..b5c1bd9ff9db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
@@ -155,6 +156,11 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
return mComponent;
}
+ @Override
+ protected LogMaker populate(LogMaker logMaker) {
+ return super.populate(logMaker).setComponentName(mComponent);
+ }
+
public Tile getQsTile() {
return mTile;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index a751ef465147..6e2add493779 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -84,12 +84,14 @@ public class QSIconViewImpl extends QSIconView {
protected void updateIcon(ImageView iv, State state) {
if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+ boolean shouldAnimate = iv.isShown() && mAnimationEnabled
+ && iv.getDrawable() != null;
Drawable d = state.icon != null
- ? iv.isShown() && mAnimationEnabled ? state.icon.getDrawable(mContext)
+ ? shouldAnimate ? state.icon.getDrawable(mContext)
: state.icon.getInvisibleDrawable(mContext) : null;
int padding = state.icon != null ? state.icon.getPadding() : 0;
if (d != null) {
- d.setAutoMirrored(true);
+ d.setAutoMirrored(false);
}
iv.setImageDrawable(d);
iv.setTag(R.id.qs_icon_tag, state.icon);
@@ -114,7 +116,7 @@ public class QSIconViewImpl extends QSIconView {
if (state.state != mState) {
int color = getColor(state.state);
mState = state.state;
- if (iv.isShown()) {
+ if (iv.isShown() && mTint != 0) {
animateGrayScale(mTint, color, iv);
mTint = color;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 948954c2bd99..1aa51b1c38bf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -14,12 +14,19 @@
package com.android.systemui.qs.tileimpl;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
+import android.metrics.LogMaker;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -29,7 +36,6 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
@@ -58,6 +64,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
protected final H mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
protected final Handler mUiHandler = new Handler(Looper.getMainLooper());
private final ArraySet<Object> mListeners = new ArraySet<>();
+ private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
protected TState mState = newTileState();
@@ -76,7 +83,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
/**
* Declare the category of this tile.
*
- * Categories are defined in {@link com.android.internal.logging.MetricsProto.MetricsEvent}
+ * Categories are defined in {@link com.android.internal.logging.nano.MetricsProto.MetricsEvent}
* by editing frameworks/base/proto/src/metrics_constants.proto.
*/
abstract public int getMetricsCategory();
@@ -152,17 +159,28 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
}
public void click() {
+ mMetricsLogger.write(populate(new LogMaker(ACTION_QS_CLICK).setType(TYPE_ACTION)));
mHandler.sendEmptyMessage(H.CLICK);
}
public void secondaryClick() {
+ mMetricsLogger.write(populate(new LogMaker(ACTION_QS_SECONDARY_CLICK).setType(TYPE_ACTION)));
mHandler.sendEmptyMessage(H.SECONDARY_CLICK);
}
public void longClick() {
+ mMetricsLogger.write(populate(new LogMaker(ACTION_QS_LONG_PRESS).setType(TYPE_ACTION)));
mHandler.sendEmptyMessage(H.LONG_CLICK);
}
+ protected LogMaker populate(LogMaker logMaker) {
+ if (mState instanceof BooleanState) {
+ logMaker.addTaggedData(FIELD_QS_VALUE, ((BooleanState) mState).value ? 1 : 0);
+ }
+ return logMaker.setSubtype(getMetricsCategory())
+ .addTaggedData(FIELD_QS_POSITION, mHost.indexOf(mTileSpec));
+ }
+
public void showDetail(boolean show) {
mHandler.obtainMessage(H.SHOW_DETAIL, show ? 1 : 0, 0).sendToTarget();
}
@@ -224,7 +242,6 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
}
protected void handleLongClick() {
- MetricsLogger.action(mContext, MetricsEvent.ACTION_QS_LONG_PRESS, getTileSpec());
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(
getLongClickIntent(), 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index c7979d84ebbb..8209ee2d5d99 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -41,8 +41,8 @@ import com.android.settingslib.graph.UsageView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.DetailAdapter;
-import com.android.systemui.qs.QSHost;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -102,7 +102,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
@Override
public CharSequence getTileLabel() {
- return mContext.getString(R.string.battery);
+ return mContext.getString(R.string.battery_detail_switch_title);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index ed6e6ef439b5..4e4de15567d4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -83,7 +83,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
protected void handleClick() {
// Secondary clicks are header clicks, just toggle.
final boolean isEnabled = (Boolean)mState.value;
- MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled);
mController.setBluetoothEnabled(!isEnabled);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index a1d3d261c4d8..22b6a634cb9a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -108,13 +108,11 @@ public class CastTile extends QSTileImpl<BooleanState> {
protected void handleClick() {
if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
- MetricsLogger.action(mContext, getMetricsCategory());
showDetail(true);
mHost.openPanels();
});
return;
}
- MetricsLogger.action(mContext, getMetricsCategory());
showDetail(true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 4351b2ca6dc0..04be7de644e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -98,7 +98,6 @@ public class CellularTile extends QSTileImpl<SignalState> {
@Override
protected void handleSecondaryClick() {
- MetricsLogger.action(mContext, getMetricsCategory());
if (mDataController.isMobileDataSupported()) {
showDetail(true);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index e33b6808d7dd..5b374b1bc286 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -84,7 +84,6 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> {
@Override
protected void handleClick() {
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
mSetting.setValue(mState.value ? 0 : 1);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 7a25140c2fa0..b7964512a2fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -87,7 +87,6 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
private void toggleDataSaver() {
mState.value = !mDataSaverController.isDataSaverEnabled();
- MetricsLogger.action(mContext, getMetricsCategory(), mState.value);
mDataSaverController.setDataSaverEnabled(mState.value);
refreshState(mState.value);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index f35de68a837d..3c2e8973cd6e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -146,7 +146,6 @@ public class DndTile extends QSTileImpl<BooleanState> {
Toast.LENGTH_LONG).show();
return;
}
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
showDetail(true);
int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
mController.setZen(zen, null, TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 7b0fd73446aa..6d2aa9065cff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -87,7 +87,6 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements
if (ActivityManager.isUserAMonkey()) {
return;
}
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
boolean newState = !mState.value;
refreshState(newState);
mFlashlightController.setFlashlight(newState);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 66629371b942..5c3f65c471bf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -106,7 +106,6 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> {
if (!isEnabled && mAirplaneMode.getValue() != 0) {
return;
}
- MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled);
mController.setHotspotEnabled(!isEnabled);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index c9533635d2a5..00cfbfa1eac7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -92,7 +92,6 @@ public class IntentTile extends QSTileImpl<State> {
@Override
protected void handleClick() {
- MetricsLogger.action(mContext, getMetricsCategory(), mIntentPackage);
sendIntent("click", mOnClick, mOnClickUri);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index b5c02cb81b04..b11b15a73093 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -81,13 +81,11 @@ public class LocationTile extends QSTileImpl<BooleanState> {
Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> {
final boolean wasEnabled = mState.value;
mHost.openPanels();
- MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled);
mController.setLocationEnabled(!wasEnabled);
});
return;
}
final boolean wasEnabled = mState.value;
- MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled);
mController.setLocationEnabled(!wasEnabled);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 32993391e29f..d147b6968856 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -85,7 +85,6 @@ public class NfcTile extends QSTileImpl<BooleanState> {
@Override
protected void handleClick() {
if (mAdapter == null) return;
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
if (!mAdapter.isEnabled()) {
mAdapter.enable();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 8b47216f17e4..8aa1e43dc106 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -54,7 +54,6 @@ public class NightDisplayTile extends QSTileImpl<BooleanState>
@Override
protected void handleClick() {
final boolean activated = !mState.value;
- MetricsLogger.action(mContext, getMetricsCategory(), activated);
mController.setActivated(activated);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 130304f8619e..fb937bd09bc2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -79,7 +79,6 @@ public class RotationLockTile extends QSTileImpl<BooleanState> {
@Override
protected void handleClick() {
if (mController == null) return;
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
final boolean newState = !mState.value;
mController.setRotationLocked(!newState);
refreshState(newState);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index fde2e0449c4e..79b4c4a87596 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -114,7 +114,6 @@ public class WifiTile extends QSTileImpl<SignalState> {
protected void handleClick() {
// Secondary clicks are header clicks, just toggle.
mState.copyTo(mStateBeforeClick);
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
mController.setWifiEnabled(!mState.value);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 5086091f7572..6c89241aebfe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -68,7 +68,6 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
@Override
public void handleClick() {
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
mProfileController.setWorkModeEnabled(!mState.value);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 6da827240f3a..d3bd89ff2e47 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -474,7 +474,7 @@ public class Recents extends SystemUI
return true;
} else {
EventBus.getDefault().send(new ShowUserToastEvent(
- R.string.recents_incompatible_app_message, Toast.LENGTH_SHORT));
+ R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
return false;
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index a5f78322fca0..b8be5800764a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -610,8 +610,8 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
if (mIncompatibleAppToastView == null) {
mIncompatibleAppToastView = Utilities.findViewStubById(this,
R.id.incompatible_app_toast_stub).inflate();
- TextView msg = (TextView) findViewById(com.android.internal.R.id.message);
- msg.setText(R.string.recents_incompatible_app_message);
+ TextView msg = findViewById(com.android.internal.R.id.message);
+ msg.setText(R.string.dock_non_resizeble_failed_to_dock_text);
}
mIncompatibleAppToastView.setVisibility(View.VISIBLE);
} else if (mIncompatibleAppToastView != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 0398f7be4cf1..21a0dc9f24e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -76,6 +76,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private TextView mNumChannelsView;
private View mChannelDisabledView;
private Switch mChannelEnabledSwitch;
+ private CheckSaveListener mCheckSaveListener;
private NotificationGuts mGutsContainer;
@@ -83,6 +84,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
super(context, attrs);
}
+ // Specify a CheckSaveListener to override when/if the user's changes are committed.
+ public interface CheckSaveListener {
+ // Invoked when importance has changed and the NotificationInfo wants to try to save it.
+ // Listener should run saveImportance unless the change should be canceled.
+ void checkSave(Runnable saveImportance);
+ }
+
public interface OnSettingsClickListener {
void onClick(View v, NotificationChannel channel, int appUid);
}
@@ -92,11 +100,14 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
final String pkg,
final List<NotificationChannel> notificationChannels,
OnSettingsClickListener onSettingsClick,
- OnClickListener onDoneClick, final Set<String> nonBlockablePkgs)
+ OnClickListener onDoneClick,
+ CheckSaveListener checkSaveListener,
+ final Set<String> nonBlockablePkgs)
throws RemoteException {
mINotificationManager = iNotificationManager;
mPkg = pkg;
mNotificationChannels = notificationChannels;
+ mCheckSaveListener = checkSaveListener;
boolean isSingleDefaultChannel = false;
if (mNotificationChannels.isEmpty()) {
throw new IllegalArgumentException("bindNotification requires at least one channel");
@@ -238,7 +249,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
doneButton.setOnClickListener(onDoneClick);
}
- public boolean hasImportanceChanged() {
+ private boolean hasImportanceChanged() {
return mSingleNotificationChannel != null &&
mStartingUserImportance != getSelectedImportance();
}
@@ -316,8 +327,12 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
@Override
public boolean handleCloseControls(boolean save) {
- if (save) {
- saveImportance();
+ if (save && hasImportanceChanged()) {
+ if (mCheckSaveListener != null) {
+ mCheckSaveListener.checkSave(() -> { saveImportance(); });
+ } else {
+ saveImportance();
+ }
}
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 8da17fa76bd7..8ba4eb57f079 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -133,6 +133,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
mViewInvertHelper.update(dark);
}
mShelfIcons.setAmbient(dark);
+ updateInteractiveness();
}
@Override
@@ -576,7 +577,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
private void updateInteractiveness() {
- mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf;
+ mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf
+ && !mDark;
setClickable(mInteractive);
setFocusable(mInteractive);
setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index aa0fcbd28650..be162667751b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -82,6 +82,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
mSignalClusterView = reinflateSignalCluster(mStatusBar);
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView);
+ // Default to showing until we know otherwise.
+ showSystemIconArea(false);
}
@Override
@@ -119,6 +121,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
.removeView(mNotificationIconAreaInner);
}
notificationIconArea.addView(mNotificationIconAreaInner);
+ // Default to showing until we know otherwise.
+ showNotificationIconArea(false);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 7b2e9979fb33..bdeab21afc0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -80,6 +80,10 @@ public class DozeParameters {
return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
}
+ public boolean getDozeSuspendDisplayStateSupported() {
+ return mContext.getResources().getBoolean(R.bool.doze_suspend_display_state_supported);
+ }
+
public int getPulseDuration(boolean pickup) {
return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
}
@@ -125,7 +129,7 @@ public class DozeParameters {
public boolean getSensorsWakeUpFully() {
return mAmbientDisplayConfiguration.alwaysOnAvailable()
&& Settings.Secure.getIntForUser(mContext.getContentResolver(),
- DOZE_SENSORS_WAKE_UP_FULLY, 1, UserHandle.USER_CURRENT) != 0;
+ DOZE_SENSORS_WAKE_UP_FULLY, 0, UserHandle.USER_CURRENT) != 0;
}
private boolean getBoolean(String propName, int resId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
index b5f56c3b8182..4d99a46e2321 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
@@ -22,6 +22,7 @@ import android.util.ArrayMap;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
@@ -33,7 +34,7 @@ public class LockscreenGestureLogger {
private ArrayMap<Integer, Integer> mLegacyMap;
private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
.setType(MetricsEvent.TYPE_ACTION);
- private MetricsLogger mMetricsLogger = new MetricsLogger();
+ private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
public LockscreenGestureLogger() {
mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length);
@@ -58,9 +59,4 @@ public class LockscreenGestureLogger {
}
return value;
}
-
- @VisibleForTesting
- void setMetricsLogger(MetricsLogger metricsLogger) {
- mMetricsLogger = metricsLogger;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 3f7e340eff21..a5d7c57206be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -417,7 +417,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
getHomeButton().setImageDrawable(mHomeDefaultIcon);
}
- final boolean showImeButton = ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0);
+ // The Accessibility button always overrides the appearance of the IME switcher
+ final boolean showImeButton =
+ !mShowAccessibilityButton && ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN)
+ != 0);
getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE);
getImeSwitchButton().setImageDrawable(mImeIcon);
@@ -545,8 +548,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
mShowAccessibilityButton = visible;
mLongClickableAccessibilityButton = longClickable;
if (visible) {
- // Accessibility button overrides Menu button.
+ // Accessibility button overrides Menu and IME switcher buttons.
setMenuVisibility(false, true);
+ getImeSwitchButton().setVisibility(View.INVISIBLE);
}
getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index bb6c8f2e1e73..53ec8c5048ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -127,7 +127,6 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
private boolean mVolumeVisible;
private boolean mCurrentUserSetup;
- private boolean mManagedProfileFocused = false;
private boolean mManagedProfileIconVisible = false;
private boolean mManagedProfileInQuietMode = false;
@@ -439,45 +438,30 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
}
}
- private void profileChanged(int userId) {
- UserInfo user = null;
- if (userId == UserHandle.USER_CURRENT) {
- try {
- user = ActivityManager.getService().getCurrentUser();
- } catch (RemoteException e) {
- // Ignore
- }
- } else {
- user = mUserManager.getUserInfo(userId);
- }
-
- mManagedProfileFocused = user != null && user.isManagedProfile();
- if (DEBUG) Log.v(TAG, "profileChanged: mManagedProfileFocused: " + mManagedProfileFocused);
- // Actually update the icon later when transition starts.
- }
-
private void updateManagedProfile() {
- if (DEBUG) {
- Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
- + mManagedProfileFocused);
- }
- final boolean showIcon;
- if (mManagedProfileFocused && !mKeyguardMonitor.isShowing()) {
- showIcon = true;
- mIconController.setIcon(mSlotManagedProfile,
- R.drawable.stat_sys_managed_profile_status,
- mContext.getString(R.string.accessibility_managed_profile));
- } else if (mManagedProfileInQuietMode) {
- showIcon = true;
- mIconController.setIcon(mSlotManagedProfile,
- R.drawable.stat_sys_managed_profile_status_off,
- mContext.getString(R.string.accessibility_managed_profile));
- } else {
- showIcon = false;
- }
- if (mManagedProfileIconVisible != showIcon) {
- mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
- mManagedProfileIconVisible = showIcon;
+ try {
+ final boolean showIcon;
+ final int userId = ActivityManager.getService().getLastResumedActivityUserId();
+ if (mUserManager.isManagedProfile(userId) && !mKeyguardMonitor.isShowing()) {
+ showIcon = true;
+ mIconController.setIcon(mSlotManagedProfile,
+ R.drawable.stat_sys_managed_profile_status,
+ mContext.getString(R.string.accessibility_managed_profile));
+ } else if (mManagedProfileInQuietMode) {
+ showIcon = true;
+ mIconController.setIcon(mSlotManagedProfile,
+ R.drawable.stat_sys_managed_profile_status_off,
+ mContext.getString(R.string.accessibility_managed_profile));
+ } else {
+ showIcon = false;
+ }
+ if (mManagedProfileIconVisible != showIcon) {
+ mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
+ mManagedProfileIconVisible = showIcon;
+ }
+ } catch (RemoteException ex) {
+ Log.w(TAG, "updateManagedProfile: ", ex);
+ // ignore
}
}
@@ -556,35 +540,16 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks,
new SynchronousUserSwitchObserver() {
@Override
public void onUserSwitching(int newUserId) throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mUserInfoController.reloadUserInfo();
- }
- });
+ mHandler.post(() -> mUserInfoController.reloadUserInfo());
}
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- updateAlarm();
- profileChanged(newUserId);
- updateQuietState();
- updateManagedProfile();
- updateForegroundInstantApps();
- }
- });
- }
-
- @Override
- public void onForegroundProfileSwitch(int newProfileId) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- profileChanged(newProfileId);
- }
+ mHandler.post(() -> {
+ updateAlarm();
+ updateQuietState();
+ updateManagedProfile();
+ updateForegroundInstantApps();
});
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c2a7500384b3..035fa1d53322 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -484,7 +484,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private ScreenPinningRequest mScreenPinningRequest;
- MetricsLogger mMetricsLogger = new MetricsLogger();
+ private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
// ensure quick settings is disabled until the current user makes it through the setup wizard
private boolean mUserSetup = false;
@@ -748,12 +748,6 @@ public class StatusBar extends SystemUI implements DemoMode,
private NavigationBarFragment mNavigationBar;
private View mNavigationBarView;
- @VisibleForTesting
- void setMetricsLogger(MetricsLogger metricsLogger) {
- mMetricsLogger = metricsLogger;
- mLockscreenGestureLogger.setMetricsLogger(metricsLogger);
- }
-
@Override
public void start() {
mNetworkController = Dependency.get(NetworkController.class);
@@ -993,16 +987,19 @@ public class StatusBar extends SystemUI implements DemoMode,
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
FragmentHostManager.get(mStatusBarWindow)
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
- CollapsedStatusBarFragment statusBarFragment = (CollapsedStatusBarFragment) fragment;
+ CollapsedStatusBarFragment statusBarFragment =
+ (CollapsedStatusBarFragment) fragment;
statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
mStatusBarView = (PhoneStatusBarView) fragment.getView();
mStatusBarView.setBar(this);
mStatusBarView.setPanel(mNotificationPanel);
mStatusBarView.setScrimController(mScrimController);
setAreThereNotifications();
+ checkBarModes();
}).getFragmentManager()
.beginTransaction()
- .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG)
+ .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
+ CollapsedStatusBarFragment.TAG)
.commit();
Dependency.get(StatusBarIconController.class).addIconGroup(
new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons)));
@@ -5785,21 +5782,19 @@ public class StatusBar extends SystemUI implements DemoMode,
startAppNotificationSettingsActivity(pkg, appUid, channel);
};
final View.OnClickListener onDoneClick = (View v) -> {
+ saveAndCloseNotificationMenu(info, row, guts, v);
+ };
+ final NotificationInfo.CheckSaveListener checkSaveListener = (Runnable saveImportance) -> {
// If the user has security enabled, show challenge if the setting is changed.
- if (info.hasImportanceChanged()
- && isLockscreenPublicMode(userHandle.getIdentifier())
+ if (isLockscreenPublicMode(userHandle.getIdentifier())
&& (mState == StatusBarState.KEYGUARD
|| mState == StatusBarState.SHADE_LOCKED)) {
- OnDismissAction dismissAction = new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- saveAndCloseNotificationMenu(info, row, guts, v);
- return true;
- }
- };
- onLockedNotificationImportanceChange(dismissAction);
+ onLockedNotificationImportanceChange(() -> {
+ saveImportance.run();
+ return true;
+ });
} else {
- saveAndCloseNotificationMenu(info, row, guts, v);
+ saveImportance.run();
}
};
@@ -5822,7 +5817,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
try {
info.bindNotification(pmUser, iNotificationManager, pkg, new ArrayList(channels),
- onSettingsClick, onDoneClick, mNonBlockablePkgs);
+ onSettingsClick, onDoneClick, checkSaveListener, mNonBlockablePkgs);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java
index 21f9a79fda06..cae76b492527 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java
@@ -24,6 +24,10 @@ public interface DeviceProvisionedController extends CallbackController<DevicePr
boolean isUserSetup(int currentUser);
int getCurrentUser();
+ default boolean isCurrentUserSetup() {
+ return isUserSetup(getCurrentUser());
+ }
+
interface DeviceProvisionedListener {
default void onDeviceProvisionedChanged() { }
default void onUserSwitched() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
index 3ee01de66fd5..21a96e2ea06a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.policy;
import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
+import android.view.Gravity;
/**
* Drawable for {@link KeyButtonView}s which contains an asset for both normal mode and light
@@ -40,6 +41,9 @@ public class KeyButtonDrawable extends LayerDrawable {
private KeyButtonDrawable(Drawable[] drawables) {
super(drawables);
+ for (int i = 0; i < drawables.length; i++) {
+ setLayerGravity(i, Gravity.CENTER);
+ }
mutate();
mHasDarkDrawable = drawables.length > 1;
setDarkIntensity(0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index cdbde5e8b0e1..5771b2819f37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -228,7 +228,7 @@ public class DozeMachineTest {
mMachine.requestState(DOZE_AOD);
- assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
+ assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
}
@Test
@@ -258,7 +258,7 @@ public class DozeMachineTest {
mMachine.requestState(DOZE_AOD);
mMachine.requestState(DOZE_REQUEST_PULSE);
- assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
+ assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
new file mode 100644
index 000000000000..2e3df2ceaefc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.doze;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.view.Display;
+
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class DozeSuspendScreenStatePreventingAdapterTest {
+
+ private DozeMachine.Service mInner;
+ private DozeSuspendScreenStatePreventingAdapter mWrapper;
+
+ @Before
+ public void setup() throws Exception {
+ mInner = mock(DozeMachine.Service.class);
+ mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner);
+ }
+
+ @Test
+ public void forwards_finish() throws Exception {
+ mWrapper.finish();
+ verify(mInner).finish();
+ }
+
+ @Test
+ public void forwards_setDozeScreenState_on() throws Exception {
+ mWrapper.setDozeScreenState(Display.STATE_ON);
+ verify(mInner).setDozeScreenState(Display.STATE_ON);
+ }
+
+ @Test
+ public void forwards_setDozeScreenState_off() throws Exception {
+ mWrapper.setDozeScreenState(Display.STATE_OFF);
+ verify(mInner).setDozeScreenState(Display.STATE_OFF);
+ }
+
+ @Test
+ public void forwards_setDozeScreenState_doze() throws Exception {
+ mWrapper.setDozeScreenState(Display.STATE_DOZE);
+ verify(mInner).setDozeScreenState(Display.STATE_DOZE);
+ }
+
+ @Test
+ public void forwards_setDozeScreenState_doze_suspend() throws Exception {
+ mWrapper.setDozeScreenState(Display.STATE_DOZE_SUSPEND);
+ verify(mInner).setDozeScreenState(Display.STATE_DOZE);
+ }
+
+ @Test
+ public void forwards_requestWakeUp() throws Exception {
+ mWrapper.requestWakeUp();
+ verify(mInner).requestWakeUp();
+ }
+
+ @Test
+ public void wrapIfNeeded_needed() throws Exception {
+ DozeParameters params = mock(DozeParameters.class);
+ when(params.getDozeSuspendDisplayStateSupported()).thenReturn(false);
+
+ assertEquals(DozeSuspendScreenStatePreventingAdapter.class,
+ DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params).getClass());
+ }
+
+ @Test
+ public void wrapIfNeeded_not_needed() throws Exception {
+ DozeParameters params = mock(DozeParameters.class);
+ when(params.getDozeSuspendDisplayStateSupported()).thenReturn(true);
+
+ assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params));
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
new file mode 100644
index 000000000000..c67cccc06169
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_MORE_SETTINGS;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.ViewUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.DetailAdapter;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSDetailTest extends SysuiTestCase {
+
+ private MetricsLogger mMetricsLogger;
+ private QSDetail mQsDetail;
+ private QSPanel mQsPanel;
+ private QuickStatusBarHeader mQuickHeader;
+ private ActivityStarter mActivityStarter;
+ private DetailAdapter mMockDetailAdapter;
+ private TestableLooper mTestableLooper;
+
+ @Before
+ public void setup() throws Exception {
+ mTestableLooper = TestableLooper.get(this);
+ mTestableLooper.runWithLooper(() -> {
+ mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
+ mQsDetail = (QSDetail) LayoutInflater.from(mContext).inflate(R.layout.qs_detail, null);
+ mQsPanel = mock(QSPanel.class);
+ mQuickHeader = mock(QuickStatusBarHeader.class);
+ mQsDetail.setQsPanel(mQsPanel, mQuickHeader);
+
+ mMockDetailAdapter = mock(DetailAdapter.class);
+ when(mMockDetailAdapter.createDetailView(any(), any(), any()))
+ .thenReturn(mock(View.class));
+ });
+ }
+
+ @Test
+ public void testShowDetail_Metrics() {
+ ViewUtils.attachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+
+ mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
+ verify(mMetricsLogger).visible(eq(mMockDetailAdapter.getMetricsCategory()));
+ mQsDetail.handleShowingDetail(null, 0, 0, false);
+ verify(mMetricsLogger).hidden(eq(mMockDetailAdapter.getMetricsCategory()));
+
+ ViewUtils.detachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+ }
+
+ @Test
+ public void testMoreSettingsButton() {
+ ViewUtils.attachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+
+ mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
+ mQsDetail.findViewById(android.R.id.button2).performClick();
+
+ int metricsCategory = mMockDetailAdapter.getMetricsCategory();
+ verify(mMetricsLogger).action(eq(ACTION_QS_MORE_SETTINGS), eq(metricsCategory));
+
+ verify(mActivityStarter).postStartActivityDismissingKeyguard(any(), anyInt());
+
+ ViewUtils.detachView(mQsDetail);
+ mTestableLooper.processAllMessages();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
new file mode 100644
index 000000000000..778ab8ef3bee
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.R.id;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSFooterTest extends LeakCheckedTest {
+
+ private QSFooter mFooter;
+ private ActivityStarter mActivityStarter;
+ private DeviceProvisionedController mDeviceProvisionedController;
+
+ @Before
+ public void setup() throws Exception {
+ injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+ mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
+ mDeviceProvisionedController = mDependency.injectMockDependency(
+ DeviceProvisionedController.class);
+ TestableLooper.get(this).runWithLooper(() -> {
+ mFooter = (QSFooter) LayoutInflater.from(mContext).inflate(R.layout.qs_footer, null);
+ });
+ }
+
+ @Test
+ public void testSettings_UserNotSetup() {
+ View settingsButton = mFooter.findViewById(id.settings_button);
+ when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
+
+ mFooter.onClick(settingsButton);
+ // Verify Settings wasn't launched.
+ verify(mActivityStarter, never()).startActivity(any(), anyBoolean());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index deb31dae6840..673ffc5d0fbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -15,14 +15,19 @@
package com.android.systemui.qs;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import android.app.FragmentController;
+import android.app.FragmentManagerNonConfig;
import android.os.Looper;
+import com.android.internal.logging.MetricsLogger;
import com.android.keyguard.CarrierText;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import android.os.Parcelable;
import android.testing.AndroidTestingRunner;
import com.android.systemui.SysuiBaseFragmentTest;
@@ -44,12 +49,15 @@ import android.widget.FrameLayout;
@RunWithLooper(setAsMainLooper = true)
public class QSFragmentTest extends SysuiBaseFragmentTest {
+ private MetricsLogger mMockMetricsLogger;
+
public QSFragmentTest() {
super(QSFragment.class);
}
@Before
public void addLeakCheckDependencies() {
+ mMockMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
new LayoutInflaterBuilder(mContext)
.replace("com.android.systemui.statusbar.policy.SplitClockView",
@@ -86,4 +94,23 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
host.destroy();
processAllMessages();
}
+
+ @Test
+ public void testSaveState() {
+ QSFragment qs = (QSFragment) mFragment;
+
+ mFragments.dispatchResume();
+ processAllMessages();
+
+ qs.setListening(true);
+ qs.setExpanded(true);
+ processAllMessages();
+ recreateFragment();
+ processAllMessages();
+
+ // Get the reference to the new fragment.
+ qs = (QSFragment) mFragment;
+ assertTrue(qs.isListening());
+ assertTrue(qs.isExpanded());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
new file mode 100644
index 000000000000..49796843af6e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.qs.customize.QSCustomizer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSPanelTest extends SysuiTestCase {
+
+ private MetricsLogger mMetricsLogger;
+ private QSPanel mQsPanel;
+ private QSTileHost mHost;
+ private QSCustomizer mCustomizer;
+
+ @Before
+ public void setup() throws Exception {
+ TestableLooper.get(this).runWithLooper(() -> {
+ mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mQsPanel = new QSPanel(mContext, null);
+ mHost = mock(QSTileHost.class);
+ when(mHost.getTiles()).thenReturn(Collections.emptyList());
+ mCustomizer = mock(QSCustomizer.class);
+ mQsPanel.setHost(mHost, mCustomizer);
+ });
+ }
+
+ @Test
+ public void testSetExpanded_Metrics() {
+ mQsPanel.setExpanded(true);
+ verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true));
+ mQsPanel.setExpanded(false);
+ verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(false));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
new file mode 100644
index 000000000000..6e7d99e49ec1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs.customize;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.qs.QSTileHost;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class TileAdapterTest extends SysuiTestCase {
+
+ private TileAdapter mTileAdapter;
+
+ @Before
+ public void setup() throws Exception {
+ TestableLooper.get(this).runWithLooper(() -> mTileAdapter = new TileAdapter(mContext));
+ }
+
+ @Test
+ public void testResetNotifiesHost() {
+ QSTileHost host = mock(QSTileHost.class);
+ mTileAdapter.resetTileSpecs(host, Collections.emptyList());
+ verify(host).changeTiles(any(), any());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
new file mode 100644
index 000000000000..59483f2df5bb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs.tileimpl;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
+import android.service.quicksettings.Tile;
+import android.testing.AndroidTestingRunner;
+import android.testing.UiThreadTest;
+import android.widget.ImageView;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile.Icon;
+import com.android.systemui.plugins.qs.QSTile.State;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+
+@RunWith(AndroidTestingRunner.class)
+@UiThreadTest
+public class QSIconViewImplTest extends SysuiTestCase {
+
+ private QSIconViewImpl mIconView;
+
+ @Before
+ public void setup() {
+ mIconView = new QSIconViewImpl(mContext);
+ }
+
+ @Test
+ public void testNoFirstAnimation() {
+ ImageView iv = mock(ImageView.class);
+ State s = new State();
+ when(iv.isShown()).thenReturn(true);
+
+ // No current icon, only the static drawable should be used.
+ s.icon = mock(Icon.class);
+ when(iv.getDrawable()).thenReturn(null);
+ mIconView.updateIcon(iv, s);
+ verify(s.icon, never()).getDrawable(any());
+ verify(s.icon).getInvisibleDrawable(any());
+
+ // Has icon, should use the standard (animated) form.
+ s.icon = mock(Icon.class);
+ when(iv.getDrawable()).thenReturn(mock(Drawable.class));
+ mIconView.updateIcon(iv, s);
+ verify(s.icon).getDrawable(any());
+ verify(s.icon, never()).getInvisibleDrawable(any());
+ }
+
+ @Test
+ public void testNoFirstFade() {
+ ImageView iv = mock(ImageView.class);
+ State s = new State();
+ s.state = Tile.STATE_ACTIVE;
+ int desiredColor = mIconView.getColor(s.state);
+ when(iv.isShown()).thenReturn(true);
+
+ mIconView.setIcon(iv, s);
+ verify(iv).setImageTintList(argThat(stateList -> stateList.getColors()[0] == desiredColor));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
new file mode 100644
index 000000000000..9ed9d28cd96c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs.tileimpl;
+
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_POSITION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_VALUE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.metrics.LogMaker;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.QSTileHost;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class QSTileImplTest extends SysuiTestCase {
+
+ public static final int POSITION = 14;
+ private TestableLooper mTestableLooper;
+ private TileImpl mTile;
+ private QSTileHost mHost;
+ private MetricsLogger mMetricsLogger;
+
+ @Before
+ public void setup() throws Exception {
+ String spec = "spec";
+ mTestableLooper = TestableLooper.get(this);
+ mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+ mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+ mHost = mock(QSTileHost.class);
+ when(mHost.indexOf(spec)).thenReturn(POSITION);
+ mTestableLooper.runWithLooper(() -> {
+ mTile = new TileImpl(mHost);
+ mTile.setTileSpec(spec);
+ });
+ }
+
+ @Test
+ public void testClick_Metrics() {
+ mTile.click();
+ verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
+ }
+
+ @Test
+ public void testSecondaryClick_Metrics() {
+ mTile.secondaryClick();
+ verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
+ }
+
+ @Test
+ public void testLongClick_Metrics() {
+ mTile.longClick();
+ verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_LONG_PRESS)));
+ }
+
+ @Test
+ public void testPopulate() {
+ LogMaker maker = mock(LogMaker.class);
+ when(maker.setSubtype(anyInt())).thenReturn(maker);
+ mTile.getState().value = true;
+ mTile.populate(maker);
+ verify(maker).addTaggedData(eq(FIELD_QS_VALUE), eq(1));
+ verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
+ }
+
+ private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
+
+ private final int mCategory;
+ public String mInvalid;
+
+ public TileLogMatcher(int category) {
+ mCategory = category;
+ }
+
+ @Override
+ public boolean matches(LogMaker arg) {
+ if (arg.getCategory() != mCategory) {
+ mInvalid = "Expected category " + mCategory + " but was " + arg.getCategory();
+ return false;
+ }
+ if (arg.getType() != TYPE_ACTION) {
+ mInvalid = "Expected type " + TYPE_ACTION + " but was " + arg.getType();
+ return false;
+ }
+ if (arg.getSubtype() != mTile.getMetricsCategory()) {
+ mInvalid = "Expected subtype " + mTile.getMetricsCategory() + " but was "
+ + arg.getSubtype();
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return mInvalid;
+ }
+ }
+
+ private static class TileImpl extends QSTileImpl<QSTile.BooleanState> {
+ protected TileImpl(QSHost host) {
+ super(host);
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleClick() {
+
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 42;
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ @Override
+ protected void setListening(boolean listening) {
+
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return null;
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 5632b719df23..21930a3d8e8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -135,7 +135,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -146,7 +146,7 @@ public class NotificationInfoTest extends SysuiTestCase {
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -154,7 +154,7 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
assertEquals(View.GONE, groupNameView.getVisibility());
final TextView groupDividerView =
@@ -171,7 +171,7 @@ public class NotificationInfoTest extends SysuiTestCase {
eq("test_group_id"), eq(TEST_PACKAGE_NAME), anyInt()))
.thenReturn(notificationChannelGroup);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
assertEquals(View.VISIBLE, groupNameView.getVisibility());
assertEquals("Test Group Name", groupNameView.getText());
@@ -183,7 +183,7 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(TEST_CHANNEL_NAME, textView.getText());
}
@@ -196,7 +196,7 @@ public class NotificationInfoTest extends SysuiTestCase {
(View v, NotificationChannel c, int appUid) -> {
assertEquals(mNotificationChannel, c);
latch.countDown();
- }, null, null);
+ }, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -214,7 +214,7 @@ public class NotificationInfoTest extends SysuiTestCase {
(View v, NotificationChannel c, int appUid) -> {
assertEquals(null, c);
latch.countDown();
- }, null, null);
+ }, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -227,7 +227,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null);
+ (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
@@ -239,7 +239,7 @@ public class NotificationInfoTest extends SysuiTestCase {
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null);
+ (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText());
@@ -251,7 +251,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null,
(View v) -> { latch.countDown(); },
- null);
+ null, null);
final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done);
doneButton.performClick();
@@ -262,7 +262,8 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testBindNotification_NumChannelsTextUniqueWhenDefaultChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(View.VISIBLE, numChannelsView.getVisibility());
@@ -274,7 +275,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
@@ -287,7 +288,7 @@ public class NotificationInfoTest extends SysuiTestCase {
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
@@ -299,7 +300,7 @@ public class NotificationInfoTest extends SysuiTestCase {
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null);
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel),
@@ -315,7 +316,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel),
- null, null, null);
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(
@@ -336,7 +337,7 @@ public class NotificationInfoTest extends SysuiTestCase {
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel,
fourthChannel),
- null, null, null);
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(
@@ -351,7 +352,7 @@ public class NotificationInfoTest extends SysuiTestCase {
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null);
+ null, null, null, null);
final TextView channelNameView =
(TextView) mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(getNumChannelsString(2), channelNameView.getText());
@@ -362,7 +363,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testEnabledSwitchInvisibleIfBundleFromDifferentChannels() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null);
+ null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
}
@@ -370,7 +371,7 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(channelDisabledView.getVisibility(), View.GONE);
@@ -380,7 +381,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(channelDisabledView.getVisibility(), View.VISIBLE);
@@ -396,35 +397,17 @@ public class NotificationInfoTest extends SysuiTestCase {
throws Exception {
mDefaultNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+ null, null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(View.VISIBLE, channelDisabledView.getVisibility());
}
@Test
- @UiThreadTest
- public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
- assertFalse(mNotificationInfo.hasImportanceChanged());
- }
-
- @Test
- public void testHasImportanceChanged_ReturnsTrueAfterChannelDisabled() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
- // Find the high button and check it.
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
- assertTrue(mNotificationInfo.hasImportanceChanged());
- }
-
- @Test
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@@ -433,7 +416,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
@@ -445,7 +428,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -457,7 +440,7 @@ public class NotificationInfoTest extends SysuiTestCase {
throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -468,7 +451,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertTrue(enabledSwitch.isChecked());
@@ -478,7 +461,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertFalse(enabledSwitch.isChecked());
@@ -488,7 +471,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testEnabledSwitchVisibleByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
@@ -498,7 +481,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -509,7 +492,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -520,7 +503,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -534,7 +517,7 @@ public class NotificationInfoTest extends SysuiTestCase {
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -543,4 +526,34 @@ public class NotificationInfoTest extends SysuiTestCase {
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
}
+
+ @Test
+ public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ (Runnable saveImportance) -> {},
+ Collections.singleton(TEST_PACKAGE_NAME));
+
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ enabledSwitch.setChecked(false);
+ mNotificationInfo.handleCloseControls(true);
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
+ }
+
+ @Test
+ public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ (Runnable saveImportance) -> { saveImportance.run(); },
+ Collections.singleton(TEST_PACKAGE_NAME));
+
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ enabledSwitch.setChecked(false);
+ mNotificationInfo.handleCloseControls(true);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index a9acda305663..6ddbffccaa96 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -104,6 +105,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
fragment.disable(0, 0, false);
- Mockito.verify(mNotificationAreaInner).setVisibility(eq(View.VISIBLE));
+ Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index f48af7557593..bf6b3946d101 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -62,9 +62,9 @@ public class StatusBarTest extends SysuiTestCase {
mKeyguardIndicationController = mock(KeyguardIndicationController.class);
mStackScroller = mock(NotificationStackScrollLayout.class);
mMetricsLogger = new FakeMetricsLogger();
+ mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
mKeyguardIndicationController, mStackScroller);
- mStatusBar.setMetricsLogger(mMetricsLogger);
doAnswer(invocation -> {
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 783aae7121ad..e8d9b7025498 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3656,7 +3656,7 @@ message MetricsEvent {
ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870;
// The name of the activity being launched in an app transition event.
- APP_TRANSITION_ACTIVITY_NAME = 871;
+ FIELD_CLASS_NAME = 871;
// ACTION: Settings > App detail > Uninstall
ACTION_SETTINGS_UNINSTALL_APP = 872;
@@ -3874,6 +3874,29 @@ message MetricsEvent {
// OPEN: Settings -> System -> Reset options
RESET_DASHBOARD = 924;
+ // ACTION: QS -> Tile clicked
+ ACTION_QS_CLICK = 925;
+
+ // ACTION: QS -> Secondary click
+ ACTION_QS_SECONDARY_CLICK = 926;
+
+ // FIELD: Position info in QS clicks
+ FIELD_QS_POSITION = 927;
+
+ // FIELD: The value of a QS tile when clicked (if applicable)
+ FIELD_QS_VALUE = 928;
+
+ // ACTION: QS -> Detail panel -> more settings
+ ACTION_QS_MORE_SETTINGS = 929;
+
+ // ACTION: QS -> Click date
+ ACTION_QS_DATE = 930;
+
+ // OPEN: Settings > Storage > Movies & TV
+ // CATEGORY: SETTINGS
+ // OS: O
+ APPLICATIONS_STORAGE_MOVIES = 931;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 05c659292e69..acaae7b298dd 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -52,6 +52,7 @@ import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.IFingerprintService;
import android.hardware.input.InputManager;
+import android.media.AudioManagerInternal;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -75,6 +76,7 @@ import android.provider.SettingsStringUtil.ComponentNameSet;
import android.provider.SettingsStringUtil.SettingStringHelper;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
+import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -220,6 +222,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList =
new ArrayList<>();
+ private final IntArray mTempIntArray = new IntArray(0);
+
private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients =
new RemoteCallbackList<>();
@@ -1558,6 +1562,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
+ final int count = userState.mBoundServices.size();
+ mTempIntArray.clear();
+ for (int i = 0; i < count; i++) {
+ final ResolveInfo resolveInfo =
+ userState.mBoundServices.get(i).mAccessibilityServiceInfo.getResolveInfo();
+ if (resolveInfo != null) {
+ mTempIntArray.add(resolveInfo.serviceInfo.applicationInfo.uid);
+ }
+ }
+ // Calling out with lock held, but to a lower-level service
+ final AudioManagerInternal audioManager =
+ LocalServices.getService(AudioManagerInternal.class);
+ if (audioManager != null) {
+ audioManager.setAccessibilityServiceUids(mTempIntArray);
+ }
updateAccessibilityEnabledSetting(userState);
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 4d783503cb5f..3d1c2511db27 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -19,15 +19,10 @@ package com.android.server.autofill;
import static android.service.autofill.AutofillService.EXTRA_ACTIVITY_TOKEN;
import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
-import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
-import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;
import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
-import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
-import static android.view.autofill.AutofillManager.FLAG_MANUAL_REQUEST;
import static com.android.server.autofill.Helper.DEBUG;
import static com.android.server.autofill.Helper.VERBOSE;
-import static com.android.server.autofill.Helper.findValue;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -35,32 +30,23 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.assist.AssistStructure;
-import android.app.assist.AssistStructure.ViewNode;
-import android.app.assist.AssistStructure.WindowNode;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.graphics.Rect;
-import android.metrics.LogMaker;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Parcelable;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserManager;
import android.provider.Settings;
import android.service.autofill.AutofillService;
import android.service.autofill.AutofillServiceInfo;
-import android.service.autofill.Dataset;
-import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
-import android.service.autofill.SaveInfo;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.LocalLog;
@@ -68,21 +54,16 @@ import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutoFillManagerClient;
-import android.view.autofill.IAutofillWindowPresenter;
+
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.IResultReceiver;
import com.android.server.autofill.ui.AutoFillUI;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
/**
* Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
@@ -93,13 +74,12 @@ final class AutofillManagerServiceImpl {
private static final String TAG = "AutofillManagerServiceImpl";
- private static final int MSG_SERVICE_SAVE = 1;
+ static final int MSG_SERVICE_SAVE = 1;
private final int mUserId;
private final Context mContext;
private final Object mLock;
private final AutoFillUI mUi;
- private final MetricsLogger mMetricsLogger = new MetricsLogger();
private RemoteCallbackList<IAutoFillManagerClient> mClients;
private AutofillServiceInfo mInfo;
@@ -358,8 +338,9 @@ final class AutofillManagerServiceImpl {
private Session createSessionByTokenLocked(@NonNull IBinder activityToken,
@Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
int flags, @NonNull String packageName) {
- final Session newSession = new Session(mContext, activityToken,
- windowToken, appCallbackToken, hasCallback, flags, packageName);
+ final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
+ activityToken, windowToken, appCallbackToken, hasCallback, flags,
+ mInfo.getServiceInfo().getComponentName(), packageName);
mSessions.put(activityToken, newSession);
/*
@@ -400,6 +381,10 @@ final class AutofillManagerServiceImpl {
session.updateLocked(autofillId, virtualBounds, value, flags);
}
+ void removeSessionLocked(IBinder activityToken) {
+ mSessions.remove(activityToken);
+ }
+
private void handleSessionSave(IBinder activityToken) {
synchronized (mLock) {
final Session session = mSessions.get(activityToken);
@@ -423,6 +408,25 @@ final class AutofillManagerServiceImpl {
mSessions.clear();
}
+ void disableSelf() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final String autoFillService = Settings.Secure.getStringForUser(
+ mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
+ if (mInfo.getServiceInfo().getComponentName().equals(
+ ComponentName.unflattenFromString(autoFillService))) {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ CharSequence getServiceLabel() {
+ return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
+ }
+
void dumpLocked(String prefix, PrintWriter pw) {
final String prefix2 = prefix + " ";
@@ -495,804 +499,4 @@ final class AutofillManagerServiceImpl {
+ ", component=" + (mInfo != null
? mInfo.getServiceInfo().getComponentName() : null) + "]";
}
-
- /**
- * State for a given view with a AutofillId.
- *
- * <p>This class holds state about a view and calls its listener when the fill UI is ready to
- * be displayed for the view.
- */
- static final class ViewState {
- interface Listener {
- /**
- * Called when the fill UI is ready to be shown for this view.
- */
- void onFillReady(FillResponse fillResponse, AutofillId focusedId,
- @Nullable AutofillValue value);
- }
-
- final AutofillId mId;
- private final Listener mListener;
- // TODO(b/33197203): would not need a reference to response and session if it was an inner
- // class of Session...
- private final Session mSession;
- // TODO(b/33197203): encapsulate access so it's not called by UI
- FillResponse mResponse;
- Intent mAuthIntent;
-
- private AutofillValue mAutofillValue;
-
- // Bounds if a virtual view, null otherwise
- private Rect mVirtualBounds;
-
- private boolean mValueUpdated;
-
- ViewState(Session session, AutofillId id, Listener listener) {
- mSession = session;
- mId = id;
- mListener = listener;
- }
-
- /**
- * Response should only be set once.
- */
- void setResponse(FillResponse response) {
- mResponse = response;
- maybeCallOnFillReady();
- }
-
- /**
- * Used when a {@link FillResponse} requires authentication to be unlocked.
- */
- void setResponse(FillResponse response, Intent authIntent) {
- mAuthIntent = authIntent;
- setResponse(response);
- }
-
- CharSequence getServiceName() {
- return mSession.getServiceName();
- }
-
- // TODO(b/33197203): need to refactor / rename / document this method to make it clear that
- // it can change the value and update the UI; similarly, should replace code that
- // directly sets mAutoFilLValue to use encapsulation.
- void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) {
- if (autofillValue != null) {
- mAutofillValue = autofillValue;
- }
- if (virtualBounds != null) {
- mVirtualBounds = virtualBounds;
- }
-
- maybeCallOnFillReady();
- }
-
- /**
- * Calls {@link
- * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the
- * fill UI is ready to be displayed (i.e. when response and bounds are set).
- */
- void maybeCallOnFillReady() {
- if (mResponse != null && (mResponse.getAuthentication() != null
- || mResponse.getDatasets() != null)) {
- mListener.onFillReady(mResponse, mId, mAutofillValue);
- }
- }
-
- @Override
- public String toString() {
- return "ViewState: [id=" + mId + ", value=" + mAutofillValue + ", bounds=" + mVirtualBounds
- + ", updated = " + mValueUpdated + "]";
- }
-
- void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("id:" ); pw.println(mId);
- pw.print(prefix); pw.print("value:" ); pw.println(mAutofillValue);
- pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated);
- pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds);
- pw.print(prefix); pw.print("authIntent:" ); pw.println(mAuthIntent);
- }
- }
-
- /**
- * A session for a given activity.
- *
- * <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track
- * of the current {@link ViewState} to display the appropriate UI.
- *
- * <p>Although the autofill requests and callbacks are stateless from the service's point of
- * view, we need to keep state in the framework side for cases such as authentication. For
- * example, when service return a {@link FillResponse} that contains all the fields needed
- * to fill the activity but it requires authentication first, that response need to be held
- * until the user authenticates or it times out.
- */
- // TODO(b/33197203): make sure sessions are removed (and tested by CTS):
- // - On all authentication scenarios.
- // - When user does not interact back after a while.
- // - When service is unbound.
- final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
- AutoFillUI.AutoFillUiCallback {
- private final IBinder mActivityToken;
- private final IBinder mWindowToken;
-
- /** Package name of the app that is auto-filled */
- @NonNull private final String mPackageName;
-
- @GuardedBy("mLock")
- private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>();
-
- @GuardedBy("mLock")
- @Nullable
- private ViewState mCurrentViewState;
-
- private final IAutoFillManagerClient mClient;
-
- @GuardedBy("mLock")
- RemoteFillService mRemoteFillService;
-
- // TODO(b/33197203): Get a response per view instead of per activity.
- @GuardedBy("mLock")
- private FillResponse mCurrentResponse;
-
- /**
- * Used to remember which {@link Dataset} filled the session.
- */
- // TODO(b/33197203): might need more than one once we support partitions
- @GuardedBy("mLock")
- private Dataset mAutoFilledDataset;
-
- /**
- * Assist structure sent by the app; it will be updated (sanitized, change values for save)
- * before sent to {@link AutofillService}.
- */
- @GuardedBy("mLock")
- private AssistStructure mStructure;
-
- /**
- * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}.
- */
- private boolean mHasCallback;
-
- /**
- * Flags used to start the session.
- */
- private int mFlags;
- private Session(@NonNull Context context, @NonNull IBinder activityToken,
- @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
- int flags, @NonNull String packageName) {
- mRemoteFillService = new RemoteFillService(context,
- mInfo.getServiceInfo().getComponentName(), mUserId, this);
- mActivityToken = activityToken;
- mWindowToken = windowToken;
- mHasCallback = hasCallback;
- mFlags = flags;
- mPackageName = packageName;
-
- mClient = IAutoFillManagerClient.Stub.asInterface(client);
- try {
- client.linkToDeath(() -> {
- if (DEBUG) {
- Slog.d(TAG, "app binder died");
- }
-
- removeSelf();
- }, 0);
- } catch (RemoteException e) {
- Slog.w(TAG, "linkToDeath() on mClient failed: " + e);
- }
-
- mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
- }
-
- // FillServiceCallbacks
- @Override
- public void onFillRequestSuccess(@Nullable FillResponse response,
- @NonNull String servicePackageName) {
- if (response == null) {
- // Nothing to be done, but need to notify client.
- notifyUnavailableToClient();
- removeSelf();
- return;
- }
-
- if ((response.getDatasets() == null || response.getDatasets().isEmpty())
- && response.getAuthentication() == null) {
- // Response is "empty" from an UI point of view, need to notify client.
- notifyUnavailableToClient();
- }
- synchronized (mLock) {
- processResponseLocked(response);
- }
-
- LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_REQUEST))
- .setType(MetricsProto.MetricsEvent.TYPE_SUCCESS)
- .setPackageName(mPackageName)
- .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
- response.getDatasets() == null ? 0 : response.getDatasets().size())
- .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
- servicePackageName);
- mMetricsLogger.write(log);
- }
-
- // FillServiceCallbacks
- @Override
- public void onFillRequestFailure(@Nullable CharSequence message,
- @NonNull String servicePackageName) {
- LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_REQUEST))
- .setType(MetricsProto.MetricsEvent.TYPE_FAILURE)
- .setPackageName(mPackageName)
- .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
- servicePackageName);
- mMetricsLogger.write(log);
-
- getUiForShowing().showError(message);
- removeSelf();
- }
-
- // FillServiceCallbacks
- @Override
- public void onSaveRequestSuccess(@NonNull String servicePackageName) {
- LogMaker log = (new LogMaker(
- MetricsProto.MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
- .setType(MetricsProto.MetricsEvent.TYPE_SUCCESS)
- .setPackageName(mPackageName)
- .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
- servicePackageName);
- mMetricsLogger.write(log);
-
- // Nothing left to do...
- removeSelf();
- }
-
- // FillServiceCallbacks
- @Override
- public void onSaveRequestFailure(@Nullable CharSequence message,
- @NonNull String servicePackageName) {
- LogMaker log = (new LogMaker(
- MetricsProto.MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
- .setType(MetricsProto.MetricsEvent.TYPE_FAILURE)
- .setPackageName(mPackageName)
- .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
- servicePackageName);
- mMetricsLogger.write(log);
-
- getUiForShowing().showError(message);
- removeSelf();
- }
-
- // FillServiceCallbacks
- @Override
- public void authenticate(IntentSender intent) {
- final Intent fillInIntent;
- synchronized (mLock) {
- fillInIntent = createAuthFillInIntent(mStructure);
- }
- mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
- }
-
- // FillServiceCallbacks
- @Override
- public void onDisableSelf() {
- final long identity = Binder.clearCallingIdentity();
- try {
- final String autoFillService = Settings.Secure.getStringForUser(
- mContext.getContentResolver(),
- Settings.Secure.AUTOFILL_SERVICE, mUserId);
- if (mInfo.getServiceInfo().getComponentName().equals(
- ComponentName.unflattenFromString(autoFillService))) {
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- synchronized (mLock) {
- removeSelfLocked();
- }
- }
-
- // FillServiceCallbacks
- @Override
- public void onServiceDied(RemoteFillService service) {
- // TODO(b/33197203): implement
- }
-
- // AutoFillUiCallback
- @Override
- public void fill(Dataset dataset) {
- mHandlerCaller.getHandler().post(() -> autoFill(dataset));
- }
-
- // AutoFillUiCallback
- @Override
- public void save() {
- mHandlerCaller.getHandler().obtainMessage(MSG_SERVICE_SAVE, mActivityToken)
- .sendToTarget();
- }
-
- // AutoFillUiCallback
- @Override
- public void cancelSave() {
- mHandlerCaller.getHandler().post(() -> removeSelf());
- }
-
- // AutoFillUiCallback
- @Override
- public void requestShowFillUi(AutofillId id, int width, int height,
- IAutofillWindowPresenter presenter) {
- try {
- mClient.requestShowFillUi(mWindowToken, id, width, height,
- mCurrentViewState.mVirtualBounds, presenter);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error requesting to show fill UI", e);
- }
- }
-
- // AutoFillUiCallback
- @Override
- public void requestHideFillUi(AutofillId id) {
- try {
- mClient.requestHideFillUi(mWindowToken, id);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error requesting to hide fill UI", e);
- }
- }
-
- public void setAuthenticationResultLocked(Bundle data) {
- if (mCurrentResponse == null || data == null) {
- removeSelf();
- } else {
- Parcelable result = data.getParcelable(
- AutofillManager.EXTRA_AUTHENTICATION_RESULT);
- if (result instanceof FillResponse) {
- mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_AUTHENTICATED,
- mPackageName);
-
- mCurrentResponse = (FillResponse) result;
- processResponseLocked(mCurrentResponse);
- } else if (result instanceof Dataset) {
- Dataset dataset = (Dataset) result;
- final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset);
- if (index >= 0) {
- mCurrentResponse.getDatasets().set(index, dataset);
- autoFill(dataset);
- }
- }
- }
- }
-
- public void setHasCallback(boolean hasIt) {
- mHasCallback = hasIt;
- }
-
- /**
- * Shows the save UI, when session can be saved.
- *
- * @return {@code true} if session is done, or {@code false} if it's pending user action.
- */
- public boolean showSaveLocked() {
- if (mStructure == null) {
- Slog.wtf(TAG, "showSaveLocked(): no mStructure");
- return true;
- }
- if (mCurrentResponse == null) {
- // Happens when the activity / session was finished before the service replied, or
- // when the service cannot autofill it (and returned a null response).
- if (DEBUG) {
- Slog.d(TAG, "showSaveLocked(): no mCurrentResponse");
- }
- return true;
- }
- final SaveInfo saveInfo = mCurrentResponse.getSaveInfo();
- if (DEBUG) {
- Slog.d(TAG, "showSaveLocked(): saveInfo=" + saveInfo);
- }
-
- /*
- * The Save dialog is only shown if all conditions below are met:
- *
- * - saveInfo is not null
- * - autofillValue of all required ids is not null
- * - autofillValue of at least one id (required or optional) has changed.
- */
-
- if (saveInfo == null) {
- return true;
- }
-
- final AutofillId[] requiredIds = saveInfo.getRequiredIds();
- if (requiredIds == null || requiredIds.length == 0) {
- Slog.w(TAG, "showSaveLocked(): no required ids on saveInfo");
- return true;
- }
-
- boolean allRequiredAreNotEmpty = true;
- boolean atLeastOneChanged = false;
- for (int i = 0; i < requiredIds.length; i++) {
- final AutofillId id = requiredIds[i];
- final ViewState state = mViewStates.get(id);
- if (state == null || state.mAutofillValue == null
- || state.mAutofillValue.isEmpty()) {
- final ViewNode node = findViewNodeByIdLocked(id);
- if (node == null) {
- Slog.w(TAG, "Service passed invalid id on SavableInfo: " + id);
- allRequiredAreNotEmpty = false;
- break;
- }
- final AutofillValue initialValue = node.getAutofillValue();
- if (initialValue == null || initialValue.isEmpty()) {
- if (DEBUG) {
- Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id );
- }
- allRequiredAreNotEmpty = false;
- break;
- }
- }
- if (state.mValueUpdated) {
- final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
- if (!state.mAutofillValue.equals(filledValue)) {
- if (DEBUG) {
- Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": "
- + filledValue + " => " + state.mAutofillValue);
- }
- atLeastOneChanged = true;
- }
- } else {
- if (state.mAutofillValue == null || state.mAutofillValue.isEmpty()) {
- if (DEBUG) {
- Slog.d(TAG, "finishSessionLocked(): empty value for " + id + ": "
- + state.mAutofillValue);
- }
- allRequiredAreNotEmpty = false;
- break;
-
- }
- }
- }
-
- if (allRequiredAreNotEmpty) {
- if (!atLeastOneChanged && saveInfo.getOptionalIds() != null) {
- for (int i = 0; i < saveInfo.getOptionalIds().length; i++) {
- final AutofillId id = saveInfo.getOptionalIds()[i];
- final ViewState state = mViewStates.get(id);
- if (state != null && state.mAutofillValue != null && state.mValueUpdated) {
- final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
- if (!state.mAutofillValue.equals(filledValue)) {
- if (DEBUG) {
- Slog.d(TAG, "finishSessionLocked(): found a change on optional "
- + id + ": " + filledValue + " => "
- + state.mAutofillValue);
- }
- atLeastOneChanged = true;
- break;
- }
- }
- }
- }
- if (atLeastOneChanged) {
- getUiForShowing().showSaveUi(
- mInfo.getServiceInfo().loadLabel(mContext.getPackageManager()),
- saveInfo, mPackageName);
- return false;
- }
- }
- // Nothing changed...
- if (DEBUG) {
- Slog.d(TAG, "showSaveLocked(): with no changes, comes no responsibilities."
- + "allRequiredAreNotNull=" + allRequiredAreNotEmpty
- + ", atLeastOneChanged=" + atLeastOneChanged);
- }
- return true;
- }
-
- /**
- * Calls service when user requested save.
- */
- private void callSaveLocked() {
- if (DEBUG) {
- Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
- }
-
- final Bundle extras = this.mCurrentResponse.getExtras();
-
- for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
- final AutofillValue value = entry.getValue().mAutofillValue;
- if (value == null) {
- if (VERBOSE) {
- Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
- }
- continue;
- }
- final AutofillId id = entry.getKey();
- final ViewNode node = findViewNodeByIdLocked(id);
- if (node == null) {
- Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
- continue;
- }
- if (VERBOSE) {
- Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
- }
-
- node.updateAutofillValue(value);
- }
-
- // Sanitize structure before it's sent to service.
- mStructure.sanitizeForParceling(false);
-
- if (VERBOSE) {
- Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
- mStructure.dump();
- }
-
- mRemoteFillService.onSaveRequest(mStructure, extras);
- }
-
- void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
- if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) {
- // TODO(b/33197203): ignoring because we don't support partitions yet
- Slog.d(TAG, "updateLocked(): ignoring " + flags + " after app was autofilled");
- return;
- }
-
- ViewState viewState = mViewStates.get(id);
- if (viewState == null) {
- viewState = new ViewState(this, id, this);
- mViewStates.put(id, viewState);
- }
-
- if ((flags & FLAG_START_SESSION) != 0) {
- // View is triggering autofill.
- mCurrentViewState = viewState;
- viewState.update(value, virtualBounds);
- return;
- }
-
- if ((flags & FLAG_VALUE_CHANGED) != 0) {
- if (value != null && !value.equals(viewState.mAutofillValue)) {
- viewState.mValueUpdated = true;
-
- // Must check if this update was caused by autofilling the view, in which
- // case we just update the value, but not the UI.
- if (mAutoFilledDataset != null) {
- final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
- if (value.equals(filledValue)) {
- viewState.mAutofillValue = value;
- return;
- }
- }
-
- // Change value
- viewState.mAutofillValue = value;
-
- // Update the chooser UI
- if (value.isText()) {
- getUiForShowing().filterFillUi(value.getTextValue().toString());
- } else {
- getUiForShowing().filterFillUi(null);
- }
- }
-
- return;
- }
-
- if ((flags & FLAG_VIEW_ENTERED) != 0) {
- // Remove the UI if the ViewState has changed.
- if (mCurrentViewState != viewState) {
- mUi.hideFillUi(mCurrentViewState != null ? mCurrentViewState.mId : null);
- mCurrentViewState = viewState;
- }
-
- // If the ViewState is ready to be displayed, onReady() will be called.
- viewState.update(value, virtualBounds);
-
- // TODO(b/33197203): Remove when there is a response per activity.
- if (mCurrentResponse != null) {
- viewState.setResponse(mCurrentResponse);
- }
-
- return;
- }
-
- if ((flags & FLAG_VIEW_EXITED) != 0) {
- if (mCurrentViewState == viewState) {
- mUi.hideFillUi(viewState.mId);
- mCurrentViewState = null;
- }
- return;
- }
-
- Slog.w(TAG, "updateLocked(): unknown flags " + flags);
- }
-
- @Override
- public void onFillReady(FillResponse response, AutofillId filledId,
- @Nullable AutofillValue value) {
- String filterText = null;
- if (value != null && value.isText()) {
- filterText = value.getTextValue().toString();
- }
-
- getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
- }
-
- private void notifyUnavailableToClient() {
- if (mCurrentViewState == null) {
- // TODO(b/33197203): temporary sanity check; should never happen
- Slog.w(TAG, "notifyUnavailable(): mCurrentViewState is null");
- return;
- }
- if (!mHasCallback) return;
- try {
- mClient.notifyNoFillUi(mWindowToken, mCurrentViewState.mId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
- + " id=" + mCurrentViewState.mId, e);
- }
- }
-
- private void processResponseLocked(FillResponse response) {
- if (DEBUG) {
- Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication()
- + "):" + response);
- }
-
- if (mCurrentViewState == null) {
- // TODO(b/33197203): temporary sanity check; should never happen
- Slog.w(TAG, "processResponseLocked(): mCurrentViewState is null");
- return;
- }
-
- mCurrentResponse = response;
-
- if (mCurrentResponse.getAuthentication() != null) {
- // Handle authentication.
- final Intent fillInIntent = createAuthFillInIntent(mStructure);
- mCurrentViewState.setResponse(mCurrentResponse, fillInIntent);
- return;
- }
-
- if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
- && response.getDatasets().size() == 1) {
- Slog.d(TAG, "autofilling manual request directly");
- autoFill(response.getDatasets().get(0));
- return;
- }
-
- mCurrentViewState.setResponse(mCurrentResponse);
- }
-
- void autoFill(Dataset dataset) {
- synchronized (mLock) {
- mAutoFilledDataset = dataset;
-
- // Autofill it directly...
- if (dataset.getAuthentication() == null) {
- autoFillApp(dataset);
- return;
- }
-
- // ...or handle authentication.
- Intent fillInIntent = createAuthFillInIntent(mStructure);
- startAuthentication(dataset.getAuthentication(), fillInIntent);
- }
- }
-
- CharSequence getServiceName() {
- return AutofillManagerServiceImpl.this.getServiceName();
- }
-
- private Intent createAuthFillInIntent(AssistStructure structure) {
- Intent fillInIntent = new Intent();
- fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
- return fillInIntent;
- }
-
- private void startAuthentication(IntentSender intent, Intent fillInIntent) {
- try {
- mClient.authenticate(intent, fillInIntent);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error launching auth intent", e);
- }
- }
-
- void dumpLocked(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
- pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
- pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse);
- pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset);
- pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState);
- pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size());
- final String prefix2 = prefix + " ";
- for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
- pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
- entry.getValue().dump(prefix2, pw);
- }
- if (VERBOSE) {
- pw.print(prefix); pw.print("mStructure: " );
- // TODO(b/33197203): add method do dump AssistStructure on pw
- if (mStructure != null) {
- pw.println("look at logcat" );
- mStructure.dump(); // dumps to logcat
- } else {
- pw.println("null");
- }
- }
- pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
- mRemoteFillService.dump(prefix, pw);
- }
-
- void autoFillApp(Dataset dataset) {
- synchronized (mLock) {
- try {
- if (DEBUG) {
- Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
- }
- mClient.autofill(mWindowToken, dataset.getFieldIds(), dataset.getFieldValues());
- } catch (RemoteException e) {
- Slog.w(TAG, "Error autofilling activity: " + e);
- }
- }
- }
-
- private AutoFillUI getUiForShowing() {
- synchronized (mLock) {
- mUi.setCallback(this);
- return mUi;
- }
- }
-
- private ViewNode findViewNodeByIdLocked(AutofillId id) {
- final int size = mStructure.getWindowNodeCount();
- for (int i = 0; i < size; i++) {
- final WindowNode window = mStructure.getWindowNodeAt(i);
- final ViewNode root = window.getRootViewNode();
- if (id.equals(root.getAutofillId())) {
- return root;
- }
- final ViewNode child = findViewNodeByIdLocked(root, id);
- if (child != null) {
- return child;
- }
- }
- return null;
- }
-
- private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) {
- final int childrenSize = parent.getChildCount();
- if (childrenSize > 0) {
- for (int i = 0; i < childrenSize; i++) {
- final ViewNode child = parent.getChildAt(i);
- if (id.equals(child.getAutofillId())) {
- return child;
- }
- final ViewNode grandChild = findViewNodeByIdLocked(child, id);
- if (grandChild != null && id.equals(grandChild.getAutofillId())) {
- return grandChild;
- }
- }
- }
- return null;
- }
-
- private void destroyLocked() {
- mRemoteFillService.destroy();
- mUi.setCallback(null);
- mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_SESSION_FINISHED,
- mPackageName);
- }
-
- void removeSelf() {
- synchronized (mLock) {
- removeSelfLocked();
- }
- }
-
- private void removeSelfLocked() {
- if (VERBOSE) {
- Slog.v(TAG, "removeSelfLocked()");
- }
- destroyLocked();
- mSessions.remove(mActivityToken);
- }
- }
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
new file mode 100644
index 000000000000..1093e9e27d93
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.autofill;
+
+import static android.view.autofill.AutofillManager.FLAG_MANUAL_REQUEST;
+import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
+import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
+import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
+import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;
+
+import static com.android.server.autofill.Helper.DEBUG;
+import static com.android.server.autofill.Helper.VERBOSE;
+import static com.android.server.autofill.Helper.findValue;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
+import android.app.assist.AssistStructure.WindowNode;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.graphics.Rect;
+import android.metrics.LogMaker;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.service.autofill.AutofillService;
+import android.service.autofill.Dataset;
+import android.service.autofill.FillResponse;
+import android.service.autofill.SaveInfo;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
+import android.view.autofill.IAutoFillManagerClient;
+import android.view.autofill.IAutofillWindowPresenter;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.os.HandlerCaller;
+import com.android.server.autofill.ui.AutoFillUI;
+
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * A session for a given activity.
+ *
+ * <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track
+ * of the current {@link ViewState} to display the appropriate UI.
+ *
+ * <p>Although the autofill requests and callbacks are stateless from the service's point of
+ * view, we need to keep state in the framework side for cases such as authentication. For
+ * example, when service return a {@link FillResponse} that contains all the fields needed
+ * to fill the activity but it requires authentication first, that response need to be held
+ * until the user authenticates or it times out.
+ */
+// TODO(b/33197203): make sure sessions are removed (and tested by CTS):
+// - On all authentication scenarios.
+// - When user does not interact back after a while.
+// - When service is unbound.
+final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
+ AutoFillUI.AutoFillUiCallback {
+ private static final String TAG = "AutofillSession";
+
+ private final AutofillManagerServiceImpl mService;
+ private final IBinder mActivityToken;
+ private final IBinder mWindowToken;
+ private final HandlerCaller mHandlerCaller;
+ private final Object mLock;
+ private final AutoFillUI mUi;
+
+ private final MetricsLogger mMetricsLogger = new MetricsLogger();
+
+ /** Package name of the app that is auto-filled */
+ @NonNull private final String mPackageName;
+
+ @GuardedBy("mLock")
+ private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>();
+
+ @GuardedBy("mLock")
+ @Nullable
+ private ViewState mCurrentViewState;
+
+ private final IAutoFillManagerClient mClient;
+
+ @GuardedBy("mLock")
+ RemoteFillService mRemoteFillService;
+
+ // TODO(b/33197203): Get a response per view instead of per activity.
+ @GuardedBy("mLock")
+ private FillResponse mCurrentResponse;
+
+ /**
+ * Used to remember which {@link Dataset} filled the session.
+ */
+ // TODO(b/33197203): might need more than one once we support partitions
+ @GuardedBy("mLock")
+ private Dataset mAutoFilledDataset;
+
+ /**
+ * Assist structure sent by the app; it will be updated (sanitized, change values for save)
+ * before sent to {@link AutofillService}.
+ */
+ @GuardedBy("mLock") AssistStructure mStructure;
+
+ /**
+ * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}.
+ */
+ private boolean mHasCallback;
+
+ /**
+ * Flags used to start the session.
+ */
+ int mFlags;
+
+ Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
+ @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
+ @NonNull Object lock, @NonNull IBinder activityToken,
+ @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
+ int flags, @NonNull ComponentName componentName, @NonNull String packageName) {
+ mService = service;
+ mLock = lock;
+ mUi = ui;
+ mHandlerCaller = handlerCaller;
+ mRemoteFillService = new RemoteFillService(context, componentName, userId, this);
+ mActivityToken = activityToken;
+ mWindowToken = windowToken;
+ mHasCallback = hasCallback;
+ mPackageName = packageName;
+ mFlags = flags;
+
+ mClient = IAutoFillManagerClient.Stub.asInterface(client);
+ try {
+ client.linkToDeath(() -> {
+ if (DEBUG) {
+ Slog.d(TAG, "app binder died");
+ }
+
+ removeSelf();
+ }, 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "linkToDeath() on mClient failed: " + e);
+ }
+
+ mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onFillRequestSuccess(@Nullable FillResponse response,
+ @NonNull String servicePackageName) {
+ if (response == null) {
+ // Nothing to be done, but need to notify client.
+ notifyUnavailableToClient();
+ removeSelf();
+ return;
+ }
+
+ if ((response.getDatasets() == null || response.getDatasets().isEmpty())
+ && response.getAuthentication() == null) {
+ // Response is "empty" from an UI point of view, need to notify client.
+ notifyUnavailableToClient();
+ }
+ synchronized (mLock) {
+ processResponseLocked(response);
+ }
+
+ LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
+ .setType(MetricsEvent.TYPE_SUCCESS)
+ .setPackageName(mPackageName)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
+ response.getDatasets() == null ? 0 : response.getDatasets().size())
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE,
+ servicePackageName);
+ mMetricsLogger.write(log);
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onFillRequestFailure(@Nullable CharSequence message,
+ @NonNull String servicePackageName) {
+ LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
+ .setType(MetricsEvent.TYPE_FAILURE)
+ .setPackageName(mPackageName)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
+ mMetricsLogger.write(log);
+
+ getUiForShowing().showError(message);
+ removeSelf();
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onSaveRequestSuccess(@NonNull String servicePackageName) {
+ LogMaker log = (new LogMaker(
+ MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
+ .setType(MetricsEvent.TYPE_SUCCESS)
+ .setPackageName(mPackageName)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
+ mMetricsLogger.write(log);
+
+ // Nothing left to do...
+ removeSelf();
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onSaveRequestFailure(@Nullable CharSequence message,
+ @NonNull String servicePackageName) {
+ LogMaker log = (new LogMaker(
+ MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
+ .setType(MetricsEvent.TYPE_FAILURE)
+ .setPackageName(mPackageName)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
+ mMetricsLogger.write(log);
+
+ getUiForShowing().showError(message);
+ removeSelf();
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void authenticate(IntentSender intent) {
+ final Intent fillInIntent;
+ synchronized (mLock) {
+ fillInIntent = createAuthFillInIntent(mStructure);
+ }
+ mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onDisableSelf() {
+ mService.disableSelf();
+ synchronized (mLock) {
+ removeSelfLocked();
+ }
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onServiceDied(RemoteFillService service) {
+ // TODO(b/33197203): implement
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void fill(Dataset dataset) {
+ mHandlerCaller.getHandler().post(() -> autoFill(dataset));
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void save() {
+ mHandlerCaller.getHandler()
+ .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, mActivityToken)
+ .sendToTarget();
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void cancelSave() {
+ mHandlerCaller.getHandler().post(() -> removeSelf());
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void requestShowFillUi(AutofillId id, int width, int height,
+ IAutofillWindowPresenter presenter) {
+ try {
+ mClient.requestShowFillUi(mWindowToken, id, width, height,
+ mCurrentViewState.mVirtualBounds, presenter);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error requesting to show fill UI", e);
+ }
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void requestHideFillUi(AutofillId id) {
+ try {
+ mClient.requestHideFillUi(mWindowToken, id);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error requesting to hide fill UI", e);
+ }
+ }
+
+ public void setAuthenticationResultLocked(Bundle data) {
+ if (mCurrentResponse == null || data == null) {
+ removeSelf();
+ } else {
+ Parcelable result = data.getParcelable(
+ AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+ if (result instanceof FillResponse) {
+ mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
+
+ mCurrentResponse = (FillResponse) result;
+ processResponseLocked(mCurrentResponse);
+ } else if (result instanceof Dataset) {
+ Dataset dataset = (Dataset) result;
+ final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset);
+ if (index >= 0) {
+ mCurrentResponse.getDatasets().set(index, dataset);
+ autoFill(dataset);
+ }
+ }
+ }
+ }
+
+ public void setHasCallback(boolean hasIt) {
+ mHasCallback = hasIt;
+ }
+
+ /**
+ * Shows the save UI, when session can be saved.
+ *
+ * @return {@code true} if session is done, or {@code false} if it's pending user action.
+ */
+ public boolean showSaveLocked() {
+ if (mStructure == null) {
+ Slog.wtf(TAG, "showSaveLocked(): no mStructure");
+ return true;
+ }
+ if (mCurrentResponse == null) {
+ // Happens when the activity / session was finished before the service replied, or
+ // when the service cannot autofill it (and returned a null response).
+ if (DEBUG) {
+ Slog.d(TAG, "showSaveLocked(): no mCurrentResponse");
+ }
+ return true;
+ }
+ final SaveInfo saveInfo = mCurrentResponse.getSaveInfo();
+ if (DEBUG) {
+ Slog.d(TAG, "showSaveLocked(): saveInfo=" + saveInfo);
+ }
+
+ /*
+ * The Save dialog is only shown if all conditions below are met:
+ *
+ * - saveInfo is not null
+ * - autofillValue of all required ids is not null
+ * - autofillValue of at least one id (required or optional) has changed.
+ */
+
+ if (saveInfo == null) {
+ return true;
+ }
+
+ final AutofillId[] requiredIds = saveInfo.getRequiredIds();
+ if (requiredIds == null || requiredIds.length == 0) {
+ Slog.w(TAG, "showSaveLocked(): no required ids on saveInfo");
+ return true;
+ }
+
+ boolean allRequiredAreNotEmpty = true;
+ boolean atLeastOneChanged = false;
+ for (int i = 0; i < requiredIds.length; i++) {
+ final AutofillId id = requiredIds[i];
+ final ViewState state = mViewStates.get(id);
+ if (state == null || state.mAutofillValue == null
+ || state.mAutofillValue.isEmpty()) {
+ final ViewNode node = findViewNodeByIdLocked(id);
+ if (node == null) {
+ Slog.w(TAG, "Service passed invalid id on SavableInfo: " + id);
+ allRequiredAreNotEmpty = false;
+ break;
+ }
+ final AutofillValue initialValue = node.getAutofillValue();
+ if (initialValue == null || initialValue.isEmpty()) {
+ if (DEBUG) {
+ Slog.d(TAG, "finishSessionLocked(): empty initial value for " + id );
+ }
+ allRequiredAreNotEmpty = false;
+ break;
+ }
+ }
+ if (state.mValueUpdated) {
+ final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
+ if (!state.mAutofillValue.equals(filledValue)) {
+ if (DEBUG) {
+ Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": "
+ + filledValue + " => " + state.mAutofillValue);
+ }
+ atLeastOneChanged = true;
+ }
+ } else {
+ if (state.mAutofillValue == null || state.mAutofillValue.isEmpty()) {
+ if (DEBUG) {
+ Slog.d(TAG, "finishSessionLocked(): empty value for " + id + ": "
+ + state.mAutofillValue);
+ }
+ allRequiredAreNotEmpty = false;
+ break;
+
+ }
+ }
+ }
+
+ if (allRequiredAreNotEmpty) {
+ if (!atLeastOneChanged && saveInfo.getOptionalIds() != null) {
+ for (int i = 0; i < saveInfo.getOptionalIds().length; i++) {
+ final AutofillId id = saveInfo.getOptionalIds()[i];
+ final ViewState state = mViewStates.get(id);
+ if (state != null && state.mAutofillValue != null && state.mValueUpdated) {
+ final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
+ if (!state.mAutofillValue.equals(filledValue)) {
+ if (DEBUG) {
+ Slog.d(TAG, "finishSessionLocked(): found a change on optional "
+ + id + ": " + filledValue + " => "
+ + state.mAutofillValue);
+ }
+ atLeastOneChanged = true;
+ break;
+ }
+ }
+ }
+ }
+ if (atLeastOneChanged) {
+ getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName);
+ return false;
+ }
+ }
+ // Nothing changed...
+ if (DEBUG) {
+ Slog.d(TAG, "showSaveLocked(): with no changes, comes no responsibilities."
+ + "allRequiredAreNotNull=" + allRequiredAreNotEmpty
+ + ", atLeastOneChanged=" + atLeastOneChanged);
+ }
+ return true;
+ }
+
+ /**
+ * Calls service when user requested save.
+ */
+ void callSaveLocked() {
+ if (DEBUG) {
+ Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
+ }
+
+ final Bundle extras = this.mCurrentResponse.getExtras();
+
+ for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
+ final AutofillValue value = entry.getValue().mAutofillValue;
+ if (value == null) {
+ if (VERBOSE) {
+ Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
+ }
+ continue;
+ }
+ final AutofillId id = entry.getKey();
+ final ViewNode node = findViewNodeByIdLocked(id);
+ if (node == null) {
+ Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
+ continue;
+ }
+ if (VERBOSE) {
+ Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
+ }
+
+ node.updateAutofillValue(value);
+ }
+
+ // Sanitize structure before it's sent to service.
+ mStructure.sanitizeForParceling(false);
+
+ if (VERBOSE) {
+ Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
+ mStructure.dump();
+ }
+
+ mRemoteFillService.onSaveRequest(mStructure, extras);
+ }
+
+ void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
+ if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) {
+ // TODO(b/33197203): ignoring because we don't support partitions yet
+ Slog.d(TAG, "updateLocked(): ignoring " + flags + " after app was autofilled");
+ return;
+ }
+
+ ViewState viewState = mViewStates.get(id);
+ if (viewState == null) {
+ viewState = new ViewState(this, id, this);
+ mViewStates.put(id, viewState);
+ }
+
+ if ((flags & FLAG_START_SESSION) != 0) {
+ // View is triggering autofill.
+ mCurrentViewState = viewState;
+ viewState.update(value, virtualBounds);
+ return;
+ }
+
+ if ((flags & FLAG_VALUE_CHANGED) != 0) {
+ if (value != null && !value.equals(viewState.mAutofillValue)) {
+ viewState.mValueUpdated = true;
+
+ // Must check if this update was caused by autofilling the view, in which
+ // case we just update the value, but not the UI.
+ if (mAutoFilledDataset != null) {
+ final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
+ if (value.equals(filledValue)) {
+ viewState.mAutofillValue = value;
+ return;
+ }
+ }
+
+ // Change value
+ viewState.mAutofillValue = value;
+
+ // Update the chooser UI
+ if (value.isText()) {
+ getUiForShowing().filterFillUi(value.getTextValue().toString());
+ } else {
+ getUiForShowing().filterFillUi(null);
+ }
+ }
+
+ return;
+ }
+
+ if ((flags & FLAG_VIEW_ENTERED) != 0) {
+ // Remove the UI if the ViewState has changed.
+ if (mCurrentViewState != viewState) {
+ mUi.hideFillUi(mCurrentViewState != null ? mCurrentViewState.mId : null);
+ mCurrentViewState = viewState;
+ }
+
+ // If the ViewState is ready to be displayed, onReady() will be called.
+ viewState.update(value, virtualBounds);
+
+ // TODO(b/33197203): Remove when there is a response per activity.
+ if (mCurrentResponse != null) {
+ viewState.setResponse(mCurrentResponse);
+ }
+
+ return;
+ }
+
+ if ((flags & FLAG_VIEW_EXITED) != 0) {
+ if (mCurrentViewState == viewState) {
+ mUi.hideFillUi(viewState.mId);
+ mCurrentViewState = null;
+ }
+ return;
+ }
+
+ Slog.w(TAG, "updateLocked(): unknown flags " + flags);
+ }
+
+ @Override
+ public void onFillReady(FillResponse response, AutofillId filledId,
+ @Nullable AutofillValue value) {
+ String filterText = null;
+ if (value != null && value.isText()) {
+ filterText = value.getTextValue().toString();
+ }
+
+ getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
+ }
+
+ private void notifyUnavailableToClient() {
+ if (mCurrentViewState == null) {
+ // TODO(b/33197203): temporary sanity check; should never happen
+ Slog.w(TAG, "notifyUnavailable(): mCurrentViewState is null");
+ return;
+ }
+ if (!mHasCallback) return;
+ try {
+ mClient.notifyNoFillUi(mWindowToken, mCurrentViewState.mId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
+ + " id=" + mCurrentViewState.mId, e);
+ }
+ }
+
+ private void processResponseLocked(FillResponse response) {
+ if (DEBUG) {
+ Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication()
+ + "):" + response);
+ }
+
+ if (mCurrentViewState == null) {
+ // TODO(b/33197203): temporary sanity check; should never happen
+ Slog.w(TAG, "processResponseLocked(): mCurrentViewState is null");
+ return;
+ }
+
+ mCurrentResponse = response;
+
+ if (mCurrentResponse.getAuthentication() != null) {
+ // Handle authentication.
+ final Intent fillInIntent = createAuthFillInIntent(mStructure);
+ mCurrentViewState.setResponse(mCurrentResponse, fillInIntent);
+ return;
+ }
+
+ if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
+ && response.getDatasets().size() == 1) {
+ Slog.d(TAG, "autofilling manual request directly");
+ autoFill(response.getDatasets().get(0));
+ return;
+ }
+
+ mCurrentViewState.setResponse(mCurrentResponse);
+ }
+
+ void autoFill(Dataset dataset) {
+ synchronized (mLock) {
+ mAutoFilledDataset = dataset;
+
+ // Autofill it directly...
+ if (dataset.getAuthentication() == null) {
+ autoFillApp(dataset);
+ return;
+ }
+
+ // ...or handle authentication.
+ Intent fillInIntent = createAuthFillInIntent(mStructure);
+ startAuthentication(dataset.getAuthentication(), fillInIntent);
+ }
+ }
+
+ CharSequence getServiceName() {
+ return mService.getServiceName();
+ }
+
+ private Intent createAuthFillInIntent(AssistStructure structure) {
+ Intent fillInIntent = new Intent();
+ fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
+ return fillInIntent;
+ }
+
+ private void startAuthentication(IntentSender intent, Intent fillInIntent) {
+ try {
+ mClient.authenticate(intent, fillInIntent);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error launching auth intent", e);
+ }
+ }
+
+ void dumpLocked(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
+ pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
+ pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse);
+ pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset);
+ pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState);
+ pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size());
+ final String prefix2 = prefix + " ";
+ for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
+ pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
+ entry.getValue().dump(prefix2, pw);
+ }
+ if (VERBOSE) {
+ pw.print(prefix); pw.print("mStructure: " );
+ // TODO(b/33197203): add method do dump AssistStructure on pw
+ if (mStructure != null) {
+ pw.println("look at logcat" );
+ mStructure.dump(); // dumps to logcat
+ } else {
+ pw.println("null");
+ }
+ }
+ pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
+ mRemoteFillService.dump(prefix, pw);
+ }
+
+ void autoFillApp(Dataset dataset) {
+ synchronized (mLock) {
+ try {
+ if (DEBUG) {
+ Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
+ }
+ mClient.autofill(mWindowToken, dataset.getFieldIds(), dataset.getFieldValues());
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error autofilling activity: " + e);
+ }
+ }
+ }
+
+ private AutoFillUI getUiForShowing() {
+ synchronized (mLock) {
+ mUi.setCallback(this);
+ return mUi;
+ }
+ }
+
+ private ViewNode findViewNodeByIdLocked(AutofillId id) {
+ final int size = mStructure.getWindowNodeCount();
+ for (int i = 0; i < size; i++) {
+ final WindowNode window = mStructure.getWindowNodeAt(i);
+ final ViewNode root = window.getRootViewNode();
+ if (id.equals(root.getAutofillId())) {
+ return root;
+ }
+ final ViewNode child = findViewNodeByIdLocked(root, id);
+ if (child != null) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) {
+ final int childrenSize = parent.getChildCount();
+ if (childrenSize > 0) {
+ for (int i = 0; i < childrenSize; i++) {
+ final ViewNode child = parent.getChildAt(i);
+ if (id.equals(child.getAutofillId())) {
+ return child;
+ }
+ final ViewNode grandChild = findViewNodeByIdLocked(child, id);
+ if (grandChild != null && id.equals(grandChild.getAutofillId())) {
+ return grandChild;
+ }
+ }
+ }
+ return null;
+ }
+
+ void destroyLocked() {
+ mRemoteFillService.destroy();
+ mUi.setCallback(null);
+ mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName);
+ }
+
+ void removeSelf() {
+ synchronized (mLock) {
+ removeSelfLocked();
+ }
+ }
+
+ void removeSelfLocked() {
+ if (VERBOSE) {
+ Slog.v(TAG, "removeSelfLocked()");
+ }
+ destroyLocked();
+ mService.removeSessionLocked(mActivityToken);
+ }
+} \ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
new file mode 100644
index 000000000000..d31dcfd061c0
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.service.autofill.FillResponse;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+
+import java.io.PrintWriter;
+
+/**
+ * State for a given view with a AutofillId.
+ *
+ * <p>This class holds state about a view and calls its listener when the fill UI is ready to
+ * be displayed for the view.
+ */
+final class ViewState {
+ interface Listener {
+ /**
+ * Called when the fill UI is ready to be shown for this view.
+ */
+ void onFillReady(FillResponse fillResponse, AutofillId focusedId,
+ @Nullable AutofillValue value);
+ }
+
+ final AutofillId mId;
+ private final Listener mListener;
+ // TODO(b/33197203): would not need a reference to response and session if it was an inner
+ // class of Session...
+ private final Session mSession;
+ private FillResponse mResponse;
+ private Intent mAuthIntent;
+
+ // TODO(b/33197203): encapsulate access so it's not called by UI
+ AutofillValue mAutofillValue;
+
+ // TODO(b/33197203): encapsulate access so it's not called by UI
+ // Bounds if a virtual view, null otherwise
+ Rect mVirtualBounds;
+
+ boolean mValueUpdated;
+
+ ViewState(Session session, AutofillId id, Listener listener) {
+ mSession = session;
+ mId = id;
+ mListener = listener;
+ }
+
+ /**
+ * Response should only be set once.
+ */
+ void setResponse(FillResponse response) {
+ mResponse = response;
+ maybeCallOnFillReady();
+ }
+
+ /**
+ * Used when a {@link FillResponse} requires authentication to be unlocked.
+ */
+ void setResponse(FillResponse response, Intent authIntent) {
+ mAuthIntent = authIntent;
+ setResponse(response);
+ }
+
+ CharSequence getServiceName() {
+ return mSession.getServiceName();
+ }
+
+ // TODO(b/33197203): need to refactor / rename / document this method to make it clear that
+ // it can change the value and update the UI; similarly, should replace code that
+ // directly sets mAutoFilLValue to use encapsulation.
+ void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) {
+ if (autofillValue != null) {
+ mAutofillValue = autofillValue;
+ }
+ if (virtualBounds != null) {
+ mVirtualBounds = virtualBounds;
+ }
+
+ maybeCallOnFillReady();
+ }
+
+ /**
+ * Calls {@link
+ * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the
+ * fill UI is ready to be displayed (i.e. when response and bounds are set).
+ */
+ void maybeCallOnFillReady() {
+ if (mResponse != null && (mResponse.getAuthentication() != null
+ || mResponse.getDatasets() != null)) {
+ mListener.onFillReady(mResponse, mId, mAutofillValue);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ViewState: [id=" + mId + ", value=" + mAutofillValue + ", bounds=" + mVirtualBounds
+ + ", updated = " + mValueUpdated + "]";
+ }
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("id:" ); pw.println(mId);
+ pw.print(prefix); pw.print("value:" ); pw.println(mAutofillValue);
+ pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated);
+ pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds);
+ pw.print(prefix); pw.print("authIntent:" ); pw.println(mAuthIntent);
+ }
+} \ No newline at end of file
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 037804e0c5e9..57d357044e5f 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3537,21 +3537,23 @@ public class BackupManagerService {
return;
}
mCancelAll = cancelAll;
- // Whoops, the current agent timed out running doBackup(). Tidy up and restage
- // it for the next time we run a backup pass.
- // !!! TODO: keep track of failure counts per agent, and blacklist those which
- // fail repeatedly (i.e. have proved themselves to be buggy).
- Slog.e(TAG, "Cancel backing up " + mCurrentPackage.packageName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, mCurrentPackage.packageName);
+ final String logPackageName = (mCurrentPackage != null)
+ ? mCurrentPackage.packageName
+ : "no_package_yet";
+ Slog.i(TAG, "Cancel backing up " + logPackageName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, logPackageName);
+ addBackupTrace("cancel of " + logPackageName + ", cancelAll=" + cancelAll);
mMonitor = monitorEvent(mMonitor,
BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
putMonitoringExtra(null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL,
mCancelAll));
- addBackupTrace(
- "cancel of " + mCurrentPackage.packageName + ", cancelAll=" + cancelAll);
errorCleanup();
if (!cancelAll) {
+ // The current agent either timed out or was cancelled running doBackup().
+ // Restage it for the next time we run a backup pass.
+ // !!! TODO: keep track of failure counts per agent, and blacklist those which
+ // fail repeatedly (i.e. have proved themselves to be buggy).
executeNextState(
mQueue.isEmpty() ? BackupState.FINAL : BackupState.RUNNING_QUEUE);
dataChangedImpl(mCurrentPackage.packageName);
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 98242f9b393a..fd44794b043c 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -679,7 +679,7 @@ public final class BatteryService extends SystemService {
pw.println("Battery service (battery) commands:");
pw.println(" help");
pw.println(" Print this help text.");
- pw.println(" set [-f] [ac|usb|wireless|status|level|present|invalid] <value>");
+ pw.println(" set [-f] [ac|usb|wireless|status|level|temp|present|invalid] <value>");
pw.println(" Force a battery property value, freezing battery state.");
pw.println(" -f: force a battery change broadcast be sent, prints new sequence.");
pw.println(" unplug [-f]");
@@ -767,6 +767,9 @@ public final class BatteryService extends SystemService {
case "level":
mBatteryProps.batteryLevel = Integer.parseInt(value);
break;
+ case "temp":
+ mBatteryProps.batteryTemperature = Integer.parseInt(value);
+ break;
case "invalid":
mInvalidCharger = Integer.parseInt(value);
break;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d02b72660709..003530e43173 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -96,7 +96,6 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -208,6 +207,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
private final int mReleasePendingIntentDelayMs;
+ private MockableSystemProperties mSystemProperties;
+
private Tethering mTethering;
private final PermissionMonitor mPermissionMonitor;
@@ -691,6 +692,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
IpConnectivityLog logger) {
if (DBG) log("ConnectivityService starting up");
+ mSystemProperties = getSystemProperties();
+
mMetricsLog = logger;
mDefaultRequest = createInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
@@ -708,7 +711,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
- mLingerDelayMs = SystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
+ mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
mContext = checkNotNull(context, "missing Context");
mNetd = checkNotNull(netManager, "missing INetworkManagementService");
@@ -735,7 +738,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
// TODO: What is the "correct" way to do determine if this is a wifi only device?
- boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
+ boolean wifiOnly = mSystemProperties.getBoolean("ro.radio.noril", false);
log("wifiOnly=" + wifiOnly);
String[] naStrings = context.getResources().getStringArray(
com.android.internal.R.array.networkAttributes);
@@ -788,8 +791,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- mTestMode = SystemProperties.get("cm.test.mode").equals("true")
- && SystemProperties.get("ro.build.type").equals("eng");
+ mTestMode = mSystemProperties.get("cm.test.mode").equals("true")
+ && mSystemProperties.get("ro.build.type").equals("eng");
mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager,
IoThread.get().getLooper(), new MockableSystemProperties());
@@ -1814,8 +1817,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Overridden for testing purposes to avoid writing to SystemProperties.
@VisibleForTesting
- protected int getDefaultTcpRwnd() {
- return SystemProperties.getInt(DEFAULT_TCP_RWND_KEY, 0);
+ protected MockableSystemProperties getSystemProperties() {
+ return new MockableSystemProperties();
}
private void updateTcpBufferSizes(NetworkAgentInfo nai) {
@@ -1853,10 +1856,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TCP_DEFAULT_INIT_RWND, getDefaultTcpRwnd());
+ Settings.Global.TCP_DEFAULT_INIT_RWND,
+ mSystemProperties.getInt("net.tcp.default_init_rwnd", 0));
final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd";
if (rwndValue != 0) {
- SystemProperties.set(sysctlKey, rwndValue.toString());
+ mSystemProperties.set(sysctlKey, rwndValue.toString());
}
}
@@ -1880,7 +1884,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public int getRestoreDefaultNetworkDelay(int networkType) {
- String restoreDefaultNetworkDelayStr = SystemProperties.get(
+ String restoreDefaultNetworkDelayStr = mSystemProperties.get(
NETWORK_RESTORE_DELAY_PROP_NAME);
if(restoreDefaultNetworkDelayStr != null &&
restoreDefaultNetworkDelayStr.length() != 0) {
@@ -3081,7 +3085,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public boolean isTetheringSupported() {
enforceTetherAccessPermission();
- int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
+ int defaultVal = (mSystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.TETHER_SUPPORTED, defaultVal) != 0)
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
@@ -3736,8 +3740,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
vpn.setAlwaysOnPackage(null, false);
return false;
}
-
- vpn.saveAlwaysOnPackage();
}
return true;
}
@@ -3898,15 +3900,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId);
mVpns.put(userId, userVpn);
-
- final ContentResolver cr = mContext.getContentResolver();
- String alwaysOnPackage = Settings.Secure.getStringForUser(cr,
- Settings.Secure.ALWAYS_ON_VPN_APP, userId);
- final boolean alwaysOnLockdown = Settings.Secure.getIntForUser(cr,
- Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, /* default */ 0, userId) != 0;
- if (alwaysOnPackage != null) {
- userVpn.setAlwaysOnPackage(alwaysOnPackage, alwaysOnLockdown);
- }
}
if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
updateLockdownVpn();
@@ -4580,11 +4573,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
++last;
String key = "net.dns" + last;
String value = dns.getHostAddress();
- SystemProperties.set(key, value);
+ mSystemProperties.set(key, value);
}
for (int i = last + 1; i <= mNumDnsEntries; ++i) {
String key = "net.dns" + i;
- SystemProperties.set(key, "");
+ mSystemProperties.set(key, "");
}
mNumDnsEntries = last;
}
diff --git a/services/core/java/com/android/server/FontManagerService.java b/services/core/java/com/android/server/FontManagerService.java
index 55a945a6fce1..f1726473c591 100644
--- a/services/core/java/com/android/server/FontManagerService.java
+++ b/services/core/java/com/android/server/FontManagerService.java
@@ -18,6 +18,7 @@ package com.android.server;
import android.content.Context;
import android.graphics.FontListParser;
+import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.text.FontConfig;
import android.util.Slog;
@@ -34,6 +35,7 @@ import java.io.IOException;
public class FontManagerService extends IFontManager.Stub {
private static final String TAG = "FontManagerService";
private static final String FONTS_CONFIG = "/system/etc/fonts.xml";
+ private static final String SYSTEM_FONT_DIR = "/system/fonts/";
@GuardedBy("mLock")
private FontConfig mConfig;
@@ -63,28 +65,22 @@ public class FontManagerService extends IFontManager.Stub {
public FontConfig getSystemFonts() {
synchronized (mLock) {
if (mConfig != null) {
- return new FontConfig(mConfig);
+ return mConfig;
}
- FontConfig config = loadFromSystem();
- if (config == null) {
+ mConfig = loadFromSystem();
+ if (mConfig == null) {
return null;
}
- for (FontConfig.Family family : config.getFamilies()) {
+ for (FontConfig.Family family : mConfig.getFamilies()) {
for (FontConfig.Font font : family.getFonts()) {
- File fontFile = new File(font.getFontName());
- try {
- font.setFd(ParcelFileDescriptor.open(
- fontFile, ParcelFileDescriptor.MODE_READ_ONLY));
- } catch (IOException e) {
- Slog.e(TAG, "Error opening font file " + font.getFontName(), e);
- }
+ File fontFile = new File(SYSTEM_FONT_DIR, font.getFontName());
+ font.setUri(Uri.fromFile(fontFile));
}
}
- mConfig = config;
- return new FontConfig(mConfig);
+ return mConfig;
}
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
new file mode 100644
index 000000000000..994adc480fb5
--- /dev/null
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.Manifest.permission.DUMP;
+
+import android.content.Context;
+import android.net.IIpSecService;
+import android.net.INetd;
+import android.net.util.NetdService;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/** @hide */
+public class IpSecService extends IIpSecService.Stub {
+ private static final String TAG = "IpSecService";
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final String NETD_SERVICE_NAME = "netd";
+
+ /** Binder context for this service */
+ private final Context mContext;
+
+ private Object mLock = new Object();
+
+ private static final int NETD_FETCH_TIMEOUT = 5000; //ms
+
+ /**
+ * Constructs a new IpSecService instance
+ *
+ * @param context Binder context for this service
+ */
+ private IpSecService(Context context) {
+ mContext = context;
+ }
+
+ static IpSecService create(Context context) throws InterruptedException {
+ final IpSecService service = new IpSecService(context);
+ service.connectNativeNetdService();
+ return service;
+ }
+
+ public void systemReady() {
+ if (isNetdAlive()) {
+ Slog.d(TAG, "IpSecService is ready");
+ } else {
+ Slog.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!");
+ }
+ }
+
+ private void connectNativeNetdService() {
+ // Avoid blocking the system server to do this
+ Thread t =
+ new Thread(
+ new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mLock) {
+ NetdService.get(NETD_FETCH_TIMEOUT);
+ }
+ }
+ });
+ t.run();
+ }
+
+ INetd getNetdInstance() {
+ final INetd netd = NetdService.getInstance();
+ if (netd == null) {
+ throw new RemoteException("Failed to Get Netd Instance").rethrowFromSystemServer();
+ }
+ return netd;
+ }
+
+ boolean isNetdAlive() {
+ synchronized (mLock) {
+ final INetd netd = getNetdInstance();
+ if (netd == null) {
+ return false;
+ }
+
+ try {
+ return netd.isAlive();
+ } catch (RemoteException re) {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+
+ pw.println("IpSecService Log:");
+ pw.println("NetdNativeService Connection: " + (isNetdAlive() ? "alive" : "dead"));
+ pw.println();
+ }
+}
diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java
index 5b627d934209..1a3bb357eb7b 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -88,9 +88,12 @@ public class NetworkScorerAppManager {
final String serviceLabel = getRecommendationServiceLabel(serviceInfo, pm);
final ComponentName useOpenWifiNetworksActivity =
findUseOpenWifiNetworksActivity(serviceInfo);
+ final String networkAvailableNotificationChannelId =
+ getNetworkAvailableNotificationChannelId(serviceInfo);
appDataList.add(
new NetworkScorerAppData(serviceInfo.applicationInfo.uid,
- serviceComponentName, serviceLabel, useOpenWifiNetworksActivity));
+ serviceComponentName, serviceLabel, useOpenWifiNetworksActivity,
+ networkAvailableNotificationChannelId));
} else {
if (VERBOSE) Log.v(TAG, serviceInfo.packageName
+ " is NOT a valid scorer/recommender.");
@@ -145,6 +148,20 @@ public class NetworkScorerAppManager {
return null;
}
+ @Nullable
+ private static String getNetworkAvailableNotificationChannelId(ServiceInfo serviceInfo) {
+ if (serviceInfo.metaData == null) {
+ if (DEBUG) {
+ Log.d(TAG, "No metadata found on " + serviceInfo.getComponentName());
+ }
+ return null;
+ }
+
+ return serviceInfo.metaData.getString(
+ NetworkScoreManager.NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA);
+ }
+
+
/**
* Get the application to use for scoring networks.
*
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 457c5f8e1f65..c68000ab00d4 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -98,6 +98,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.os.AppFuseMount;
import com.android.internal.os.FuseAppLoop;
+import com.android.internal.os.FuseUnavailableMountException;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
@@ -3007,32 +3008,36 @@ class StorageManagerService extends IStorageManager.Stub
}
}
- private ParcelFileDescriptor mountAppFuse(int uid, int mountId)
- throws NativeDaemonConnectorException {
- final NativeDaemonEvent event = StorageManagerService.this.mConnector.execute(
- "appfuse", "mount", uid, Process.myPid(), mountId);
- if (event.getFileDescriptors() == null ||
- event.getFileDescriptors().length == 0) {
- throw new NativeDaemonConnectorException("Cannot obtain device FD");
+ class AppFuseMountScope extends AppFuseBridge.MountScope {
+ boolean opened = false;
+
+ public AppFuseMountScope(int uid, int pid, int mountId) {
+ super(uid, pid, mountId);
}
- return new ParcelFileDescriptor(event.getFileDescriptors()[0]);
- }
- class AppFuseMountScope extends AppFuseBridge.MountScope {
- public AppFuseMountScope(int uid, int pid, int mountId)
- throws NativeDaemonConnectorException {
- super(uid, pid, mountId, mountAppFuse(uid, mountId));
+ @Override
+ public ParcelFileDescriptor open() throws NativeDaemonConnectorException {
+ final NativeDaemonEvent event = StorageManagerService.this.mConnector.execute(
+ "appfuse", "mount", uid, Process.myPid(), mountId);
+ opened = true;
+ if (event.getFileDescriptors() == null ||
+ event.getFileDescriptors().length == 0) {
+ throw new NativeDaemonConnectorException("Cannot obtain device FD");
+ }
+ return new ParcelFileDescriptor(event.getFileDescriptors()[0]);
}
@Override
public void close() throws Exception {
- super.close();
- mConnector.execute("appfuse", "unmount", uid, Process.myPid(), mountId);
+ if (opened) {
+ mConnector.execute("appfuse", "unmount", uid, Process.myPid(), mountId);
+ opened = false;
+ }
}
}
@Override
- public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
+ public @Nullable AppFuseMount mountProxyFileDescriptorBridge() {
Slog.v(TAG, "mountProxyFileDescriptorBridge");
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
@@ -3049,12 +3054,12 @@ class StorageManagerService extends IStorageManager.Stub
final int name = mNextAppFuseName++;
try {
return new AppFuseMount(
- name,
- mAppFuseBridge.addBridge(new AppFuseMountScope(uid, pid, name)));
- } catch (AppFuseBridge.BridgeException e) {
+ name, mAppFuseBridge.addBridge(new AppFuseMountScope(uid, pid, name)));
+ } catch (FuseUnavailableMountException e) {
if (newlyCreated) {
// If newly created bridge fails, it's a real error.
- throw new RemoteException(e.getMessage());
+ Slog.e(TAG, "", e);
+ return null;
}
// It seems the thread of mAppFuseBridge has already been terminated.
mAppFuseBridge = null;
@@ -3067,19 +3072,21 @@ class StorageManagerService extends IStorageManager.Stub
}
@Override
- public ParcelFileDescriptor openProxyFileDescriptor(int mountId, int fileId, int mode)
- throws RemoteException {
- Slog.v(TAG, "mountProxyFileDescriptorBridge");
+ public @Nullable ParcelFileDescriptor openProxyFileDescriptor(
+ int mountId, int fileId, int mode) {
+ Slog.v(TAG, "mountProxyFileDescriptor");
final int pid = Binder.getCallingPid();
try {
synchronized (mAppFuseLock) {
if (mAppFuseBridge == null) {
- throw new RemoteException("Cannot find mount point");
+ Slog.e(TAG, "FuseBridge has not been created");
+ return null;
}
return mAppFuseBridge.openFile(pid, mountId, fileId, mode);
}
- } catch (FileNotFoundException | SecurityException | InterruptedException error) {
- throw new RemoteException(error.getMessage());
+ } catch (FuseUnavailableMountException | InterruptedException error) {
+ Slog.v(TAG, "The mount point has already been invalid", error);
+ return null;
}
}
diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java
index 1bc6250d699a..fd88d2609c25 100644
--- a/services/core/java/com/android/server/UiThread.java
+++ b/services/core/java/com/android/server/UiThread.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.os.Handler;
+import android.os.Looper;
import android.os.Process;
import android.os.Trace;
@@ -26,20 +27,28 @@ import android.os.Trace;
* on it to avoid UI jank.
*/
public final class UiThread extends ServiceThread {
+ private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
private static UiThread sInstance;
private static Handler sHandler;
private UiThread() {
super("android.ui", Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
+ }
+
+ @Override
+ public void run() {
// Make sure UiThread is in the fg stune boost group
Process.setThreadGroup(Process.myTid(), Process.THREAD_GROUP_TOP_APP);
+ super.run();
}
private static void ensureThreadLocked() {
if (sInstance == null) {
sInstance = new UiThread();
sInstance.start();
- sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ final Looper looper = sInstance.getLooper();
+ looper.setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ looper.setSlowDispatchThresholdMs(SLOW_DISPATCH_THRESHOLD_MS);
sHandler = new Handler(sInstance.getLooper());
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java b/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java
index c3b7e15e43b6..6380da5e2af8 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java
@@ -100,18 +100,20 @@ public final class AccountManagerBackupHelper {
Account account = null;
AccountManagerService.UserAccounts accounts = mAccountManagerService
.getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
- for (Account[] accountsPerType : accounts.accountCache.values()) {
- for (Account accountPerType : accountsPerType) {
- if (accountDigest.equals(PackageUtils.computeSha256Digest(
- accountPerType.name.getBytes()))) {
- account = accountPerType;
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ for (Account[] accountsPerType : accounts.accountCache.values()) {
+ for (Account accountPerType : accountsPerType) {
+ if (accountDigest.equals(PackageUtils.computeSha256Digest(
+ accountPerType.name.getBytes()))) {
+ account = accountPerType;
+ break;
+ }
+ }
+ if (account != null) {
break;
}
}
- if (account != null) {
- break;
- }
}
}
if (account == null) {
@@ -141,49 +143,52 @@ public final class AccountManagerBackupHelper {
public byte[] backupAccountAccessPermissions(int userId) {
final AccountManagerService.UserAccounts accounts = mAccountManagerService
.getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
- List<Pair<String, Integer>> allAccountGrants = accounts.accountsDb
- .findAllAccountGrants();
- if (allAccountGrants.isEmpty()) {
- return null;
- }
- try {
- ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
- final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
- serializer.startDocument(null, true);
- serializer.startTag(null, TAG_PERMISSIONS);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ List<Pair<String, Integer>> allAccountGrants = accounts.accountsDb
+ .findAllAccountGrants();
+ if (allAccountGrants.isEmpty()) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ final XmlSerializer serializer = new FastXmlSerializer();
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_PERMISSIONS);
- PackageManager packageManager = mAccountManagerService.mContext.getPackageManager();
- for (Pair<String, Integer> grant : allAccountGrants) {
- final String accountName = grant.first;
- final int uid = grant.second;
+ PackageManager packageManager = mAccountManagerService.mContext
+ .getPackageManager();
+ for (Pair<String, Integer> grant : allAccountGrants) {
+ final String accountName = grant.first;
+ final int uid = grant.second;
- final String[] packageNames = packageManager.getPackagesForUid(uid);
- if (packageNames == null) {
- continue;
- }
+ final String[] packageNames = packageManager.getPackagesForUid(uid);
+ if (packageNames == null) {
+ continue;
+ }
- for (String packageName : packageNames) {
- String digest = PackageUtils.computePackageCertSha256Digest(
- packageManager, packageName, userId);
- if (digest != null) {
- serializer.startTag(null, TAG_PERMISSION);
- serializer.attribute(null, ATTR_ACCOUNT_SHA_256,
- PackageUtils.computeSha256Digest(accountName.getBytes()));
- serializer.attribute(null, ATTR_PACKAGE, packageName);
- serializer.attribute(null, ATTR_DIGEST, digest);
- serializer.endTag(null, TAG_PERMISSION);
+ for (String packageName : packageNames) {
+ String digest = PackageUtils.computePackageCertSha256Digest(
+ packageManager, packageName, userId);
+ if (digest != null) {
+ serializer.startTag(null, TAG_PERMISSION);
+ serializer.attribute(null, ATTR_ACCOUNT_SHA_256,
+ PackageUtils.computeSha256Digest(accountName.getBytes()));
+ serializer.attribute(null, ATTR_PACKAGE, packageName);
+ serializer.attribute(null, ATTR_DIGEST, digest);
+ serializer.endTag(null, TAG_PERMISSION);
+ }
}
}
+ serializer.endTag(null, TAG_PERMISSIONS);
+ serializer.endDocument();
+ serializer.flush();
+ return dataStream.toByteArray();
+ } catch (IOException e) {
+ Log.e(TAG, "Error backing up account access grants", e);
+ return null;
}
- serializer.endTag(null, TAG_PERMISSIONS);
- serializer.endDocument();
- serializer.flush();
- return dataStream.toByteArray();
- } catch (IOException e) {
- Log.e(TAG, "Error backing up account access grants", e);
- return null;
}
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 8e3e3eaa1a60..0ccaf8e914b8 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -114,7 +114,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -201,17 +200,19 @@ public class AccountManagerService
private final HashMap<Account, Integer> signinRequiredNotificationIds =
new HashMap<Account, Integer>();
final Object cacheLock = new Object();
+ final Object dbLock = new Object(); // if needed, dbLock must be obtained before cacheLock
/** protected by the {@link #cacheLock} */
- final HashMap<String, Account[]> accountCache =
- new LinkedHashMap<>();
+ final HashMap<String, Account[]> accountCache = new LinkedHashMap<>();
/** protected by the {@link #cacheLock} */
private final Map<Account, Map<String, String>> userDataCache = new HashMap<>();
/** protected by the {@link #cacheLock} */
private final Map<Account, Map<String, String>> authTokenCache = new HashMap<>();
/** protected by the {@link #cacheLock} */
private final TokenCache accountTokenCaches = new TokenCache();
+ /** protected by the {@link #cacheLock} */
+ private final Map<Account, Map<String, Integer>> visibilityCache = new HashMap<>();
- /** protected by the {@link #mReceiversForType}
+ /** protected by the {@link #mReceiversForType},
* type -> (packageName -> number of active receivers)
* type == null is used to get notifications about all account types
*/
@@ -237,8 +238,10 @@ public class AccountManagerService
UserAccounts(Context context, int userId, File preNDbFile, File deDbFile) {
this.userId = userId;
- synchronized (cacheLock) {
- accountsDb = AccountsDb.create(context, userId, preNDbFile, deDbFile);
+ synchronized (dbLock) {
+ synchronized (cacheLock) {
+ accountsDb = AccountsDb.create(context, userId, preNDbFile, deDbFile);
+ }
}
}
}
@@ -499,12 +502,14 @@ public class AccountManagerService
Map<Account, Integer> result = new LinkedHashMap<>();
for (String accountType : accountTypes) {
- synchronized (accounts.cacheLock) {
- final Account[] accountsOfType = accounts.accountCache.get(accountType);
- if (accountsOfType != null) {
- for (Account account : accountsOfType) {
- result.put(account,
- resolveAccountVisibility(account, packageName, accounts));
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ final Account[] accountsOfType = accounts.accountCache.get(accountType);
+ if (accountsOfType != null) {
+ for (Account account : accountsOfType) {
+ result.put(account,
+ resolveAccountVisibility(account, packageName, accounts));
+ }
}
}
}
@@ -524,25 +529,31 @@ public class AccountManagerService
String.format("uid %s cannot get secrets for account %s", callingUid, account);
throw new SecurityException(msg);
}
- return getPackagesAndVisibilityForAccount(account, accounts);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ return getPackagesAndVisibilityForAccountLocked(account, accounts);
+ }
+ }
}
/**
- * Returns all package names and visibility values, which were set for given account.
+ * Returns Map with all package names and visibility values for given account.
+ * The method and returned map must be guarded by accounts.cacheLock
*
* @param account Account to get visibility values.
* @param accounts UserAccount that currently hosts the account and application
*
- * @return Map from package names to visibility.
+ * @return Map with cache for package names to visibility.
*/
- private Map<String, Integer> getPackagesAndVisibilityForAccount(Account account,
+ private @NonNull Map<String, Integer> getPackagesAndVisibilityForAccountLocked(Account account,
UserAccounts accounts) {
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- try {
- return accounts.accountsDb.findAllVisibilityValuesForAccount(account);
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
+ Map<String, Integer> accountVisibility = accounts.visibilityCache.get(account);
+ if (accountVisibility == null) {
+ Log.d(TAG, "Visibility was not initialized");
+ accountVisibility = new HashMap<>();
+ accounts.visibilityCache.put(account, accountVisibility);
}
+ return accountVisibility;
}
@Override
@@ -572,14 +583,13 @@ public class AccountManagerService
* @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored.
*
*/
- private int getAccountVisibility(Account account, String packageName, UserAccounts accounts) {
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- try {
- Integer visibility =
- accounts.accountsDb.findAccountVisibility(account, packageName);
+ private int getAccountVisibilityFromCache(Account account, String packageName,
+ UserAccounts accounts) {
+ synchronized (accounts.cacheLock) {
+ Map<String, Integer> accountVisibility =
+ getPackagesAndVisibilityForAccountLocked(account, accounts);
+ Integer visibility = accountVisibility.get(packageName);
return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED;
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
}
}
@@ -595,9 +605,7 @@ public class AccountManagerService
*/
private Integer resolveAccountVisibility(Account account, @NonNull String packageName,
UserAccounts accounts) {
-
Preconditions.checkNotNull(packageName, "packageName cannot be null");
-
int uid = -1;
try {
long identityToken = clearCallingIdentity();
@@ -630,7 +638,7 @@ public class AccountManagerService
}
// Return stored value if it was set.
- int visibility = getAccountVisibility(account, packageName, accounts);
+ int visibility = getAccountVisibilityFromCache(account, packageName, accounts);
if (AccountManager.VISIBILITY_UNDEFINED != visibility) {
return visibility;
@@ -652,13 +660,13 @@ public class AccountManagerService
|| canReadContacts || isPrivileged) {
// Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature
// match.
- visibility = getAccountVisibility(account,
+ visibility = getAccountVisibilityFromCache(account,
AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts);
if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
}
} else {
- visibility = getAccountVisibility(account,
+ visibility = getAccountVisibilityFromCache(account,
AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts);
if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE;
@@ -727,57 +735,73 @@ public class AccountManagerService
*/
private boolean setAccountVisibility(Account account, String packageName, int newVisibility,
boolean notify, UserAccounts accounts) {
- synchronized (accounts.cacheLock) {
- Map<String, Integer> packagesToVisibility;
- if (notify) {
- if (isSpecialPackageKey(packageName)) {
- packagesToVisibility =
- getRequestingPackages(account, accounts);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ Map<String, Integer> packagesToVisibility;
+ if (notify) {
+ if (isSpecialPackageKey(packageName)) {
+ packagesToVisibility =
+ getRequestingPackages(account, accounts);
+ } else {
+ if (!packageExistsForUser(packageName, accounts.userId)) {
+ return false; // package is not installed.
+ }
+ packagesToVisibility = new HashMap<>();
+ packagesToVisibility.put(packageName,
+ resolveAccountVisibility(account, packageName, accounts));
+ }
} else {
- if (!packageExistsForUser(packageName, accounts.userId)) {
- return false; // package is not installed.
+ // Notifications will not be send.
+ if (!isSpecialPackageKey(packageName) &&
+ !packageExistsForUser(packageName, accounts.userId)) {
+ // package is not installed and not meta value.
+ return false;
}
packagesToVisibility = new HashMap<>();
- packagesToVisibility.put(packageName,
- resolveAccountVisibility(account, packageName, accounts));
}
- } else {
- // Notifications will not be send.
- if (!isSpecialPackageKey(packageName) &&
- !packageExistsForUser(packageName, accounts.userId)) {
- // package is not installed and not meta value.
- return false;
- }
- packagesToVisibility = new HashMap<>();
- }
-
- final long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId < 0) {
- return false;
- }
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
- try {
- if (!accounts.accountsDb.setAccountVisibility(accountId, packageName,
- newVisibility)) {
+ if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) {
return false;
}
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
- if (notify) {
- for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) {
- if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) {
- notifyPackage(packageToVisibility.getKey(), accounts);
+ if (notify) {
+ for (Entry<String, Integer> packageToVisibility : packagesToVisibility
+ .entrySet()) {
+ if (packageToVisibility.getValue()
+ != AccountManager.VISIBILITY_NOT_VISIBLE) {
+ notifyPackage(packageToVisibility.getKey(), accounts);
+ }
}
+ sendAccountsChangedBroadcast(accounts.userId);
}
- sendAccountsChangedBroadcast(accounts.userId);
+ return true;
}
- return true;
}
}
+ // Update account visibility in cache and database.
+ private boolean updateAccountVisibilityLocked(Account account, String packageName,
+ int newVisibility, UserAccounts accounts) {
+ final long accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId < 0) {
+ return false;
+ }
+
+ final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
+ try {
+ if (!accounts.accountsDb.setAccountVisibility(accountId, packageName,
+ newVisibility)) {
+ return false;
+ }
+ } finally {
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+ Map<String, Integer> accountVisibility =
+ getPackagesAndVisibilityForAccountLocked(account, accounts);
+ accountVisibility.put(packageName, newVisibility);
+ return true;
+ }
+
@Override
public void registerAccountListener(String[] accountTypes, String opPackageName) {
int callingUid = Binder.getCallingUid();
@@ -956,23 +980,24 @@ public class AccountManagerService
mAuthenticatorCache, accounts.userId);
boolean userUnlocked = isLocalUnlockedUser(accounts.userId);
- synchronized (accounts.cacheLock) {
- boolean accountDeleted = false;
-
- // Get a map of stored authenticator types to UID
- final AccountsDb accountsDb = accounts.accountsDb;
- Map<String, Integer> metaAuthUid = accountsDb.findMetaAuthUid();
- // Create a list of authenticator type whose previous uid no longer exists
- HashSet<String> obsoleteAuthType = Sets.newHashSet();
- SparseBooleanArray knownUids = null;
- for (Entry<String, Integer> authToUidEntry : metaAuthUid.entrySet()) {
- String type = authToUidEntry.getKey();
- int uid = authToUidEntry.getValue();
- Integer knownUid = knownAuth.get(type);
- if (knownUid != null && uid == knownUid) {
- // Remove it from the knownAuth list if it's unchanged.
- knownAuth.remove(type);
- } else {
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ boolean accountDeleted = false;
+
+ // Get a map of stored authenticator types to UID
+ final AccountsDb accountsDb = accounts.accountsDb;
+ Map<String, Integer> metaAuthUid = accountsDb.findMetaAuthUid();
+ // Create a list of authenticator type whose previous uid no longer exists
+ HashSet<String> obsoleteAuthType = Sets.newHashSet();
+ SparseBooleanArray knownUids = null;
+ for (Entry<String, Integer> authToUidEntry : metaAuthUid.entrySet()) {
+ String type = authToUidEntry.getKey();
+ int uid = authToUidEntry.getValue();
+ Integer knownUid = knownAuth.get(type);
+ if (knownUid != null && uid == knownUid) {
+ // Remove it from the knownAuth list if it's unchanged.
+ knownAuth.remove(type);
+ } else {
/*
* The authenticator is presently not cached and should only be triggered
* when we think an authenticator has been removed (or is being updated).
@@ -989,87 +1014,95 @@ public class AccountManagerService
* uninstalled while the authenticator's package is being updated.
*
*/
- if (knownUids == null) {
- knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
- }
- if (!knownUids.get(uid)) {
- // The authenticator is not presently available to the cache. And the
- // package no longer has a data directory (so we surmise it isn't updating).
- // So purge its data from the account databases.
- obsoleteAuthType.add(type);
- // And delete it from the TABLE_META
- accountsDb.deleteMetaByAuthTypeAndUid(type, uid);
+ if (knownUids == null) {
+ knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
+ }
+ if (!knownUids.get(uid)) {
+ // The authenticator is not presently available to the cache. And the
+ // package no longer has a data directory (so we surmise it isn't
+ // updating). So purge its data from the account databases.
+ obsoleteAuthType.add(type);
+ // And delete it from the TABLE_META
+ accountsDb.deleteMetaByAuthTypeAndUid(type, uid);
+ }
}
}
- }
- // Add the newly registered authenticator to TABLE_META. If old authenticators have
- // been re-enabled (after being updated for example), then we just overwrite the old
- // values.
- for (Entry<String, Integer> entry : knownAuth.entrySet()) {
- accountsDb.insertOrReplaceMetaAuthTypeAndUid(entry.getKey(), entry.getValue());
- }
+ // Add the newly registered authenticator to TABLE_META. If old authenticators have
+ // been re-enabled (after being updated for example), then we just overwrite the old
+ // values.
+ for (Entry<String, Integer> entry : knownAuth.entrySet()) {
+ accountsDb.insertOrReplaceMetaAuthTypeAndUid(entry.getKey(), entry.getValue());
+ }
- final Map<Long, Account> accountsMap = accountsDb.findAllDeAccounts();
- try {
- accounts.accountCache.clear();
- final HashMap<String, ArrayList<String>> accountNamesByType = new LinkedHashMap<>();
- for (Entry<Long, Account> accountEntry : accountsMap.entrySet()) {
- final long accountId = accountEntry.getKey();
- final Account account = accountEntry.getValue();
- if (obsoleteAuthType.contains(account.type)) {
- Slog.w(TAG, "deleting account " + account.name + " because type "
- + account.type + "'s registered authenticator no longer exist.");
- Map<String, Integer> packagesToVisibility =
- getRequestingPackages(account, accounts);
- accountsDb.beginTransaction();
- try {
- accountsDb.deleteDeAccount(accountId);
- // Also delete from CE table if user is unlocked; if user is currently
- // locked the account will be removed later by syncDeCeAccountsLocked
- if (userUnlocked) {
- accountsDb.deleteCeAccount(accountId);
+ final Map<Long, Account> accountsMap = accountsDb.findAllDeAccounts();
+ try {
+ accounts.accountCache.clear();
+ final HashMap<String, ArrayList<String>> accountNamesByType
+ = new LinkedHashMap<>();
+ for (Entry<Long, Account> accountEntry : accountsMap.entrySet()) {
+ final long accountId = accountEntry.getKey();
+ final Account account = accountEntry.getValue();
+ if (obsoleteAuthType.contains(account.type)) {
+ Slog.w(TAG, "deleting account " + account.name + " because type "
+ + account.type
+ + "'s registered authenticator no longer exist.");
+ Map<String, Integer> packagesToVisibility =
+ getRequestingPackages(account, accounts);
+ accountsDb.beginTransaction();
+ try {
+ accountsDb.deleteDeAccount(accountId);
+ // Also delete from CE table if user is unlocked; if user is
+ // currently locked the account will be removed later by
+ // syncDeCeAccountsLocked
+ if (userUnlocked) {
+ accountsDb.deleteCeAccount(accountId);
+ }
+ accountsDb.setTransactionSuccessful();
+ } finally {
+ accountsDb.endTransaction();
}
- accountsDb.setTransactionSuccessful();
- } finally {
- accountsDb.endTransaction();
- }
- accountDeleted = true;
+ accountDeleted = true;
- logRecord(AccountsDb.DEBUG_ACTION_AUTHENTICATOR_REMOVE,
- AccountsDb.TABLE_ACCOUNTS, accountId, accounts);
+ logRecord(AccountsDb.DEBUG_ACTION_AUTHENTICATOR_REMOVE,
+ AccountsDb.TABLE_ACCOUNTS, accountId, accounts);
- accounts.userDataCache.remove(account);
- accounts.authTokenCache.remove(account);
- accounts.accountTokenCaches.remove(account);
+ accounts.userDataCache.remove(account);
+ accounts.authTokenCache.remove(account);
+ accounts.accountTokenCaches.remove(account);
+ accounts.visibilityCache.remove(account);
- for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) {
- if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) {
- notifyPackage(packageToVisibility.getKey(), accounts);
+ for (Entry<String, Integer> packageToVisibility :
+ packagesToVisibility.entrySet()) {
+ if (packageToVisibility.getValue()
+ != AccountManager.VISIBILITY_NOT_VISIBLE) {
+ notifyPackage(packageToVisibility.getKey(), accounts);
+ }
}
+ } else {
+ ArrayList<String> accountNames = accountNamesByType.get(account.type);
+ if (accountNames == null) {
+ accountNames = new ArrayList<>();
+ accountNamesByType.put(account.type, accountNames);
+ }
+ accountNames.add(account.name);
}
- } else {
- ArrayList<String> accountNames = accountNamesByType.get(account.type);
- if (accountNames == null) {
- accountNames = new ArrayList<>();
- accountNamesByType.put(account.type, accountNames);
+ }
+ for (Map.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) {
+ final String accountType = cur.getKey();
+ final ArrayList<String> accountNames = cur.getValue();
+ final Account[] accountsForType = new Account[accountNames.size()];
+ for (int i = 0; i < accountsForType.length; i++) {
+ accountsForType[i] = new Account(accountNames.get(i), accountType,
+ UUID.randomUUID().toString());
}
- accountNames.add(account.name);
+ accounts.accountCache.put(accountType, accountsForType);
}
- }
- for (Map.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) {
- final String accountType = cur.getKey();
- final ArrayList<String> accountNames = cur.getValue();
- final Account[] accountsForType = new Account[accountNames.size()];
- for (int i = 0; i < accountsForType.length; i++) {
- accountsForType[i] = new Account(accountNames.get(i), accountType,
- UUID.randomUUID().toString());
+ accounts.visibilityCache.putAll(accountsDb.findAllVisibilityValues());
+ } finally {
+ if (accountDeleted) {
+ sendAccountsChangedBroadcast(accounts.userId);
}
- accounts.accountCache.put(accountType, accountsForType);
- }
- } finally {
- if (accountDeleted) {
- sendAccountsChangedBroadcast(accounts.userId);
}
}
}
@@ -1129,9 +1162,11 @@ public class AccountManagerService
// open CE database if necessary
if (!accounts.accountsDb.isCeDatabaseAttached() && mLocalUnlockedUsers.get(userId)) {
Log.i(TAG, "User " + userId + " is unlocked - opening CE database");
- synchronized (accounts.cacheLock) {
- File ceDatabaseFile = new File(mInjector.getCeDatabaseName(userId));
- accounts.accountsDb.attachCeDatabase(ceDatabaseFile);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ File ceDatabaseFile = new File(mInjector.getCeDatabaseName(userId));
+ accounts.accountsDb.attachCeDatabase(ceDatabaseFile);
+ }
}
syncDeCeAccountsLocked(accounts);
}
@@ -1166,34 +1201,50 @@ public class AccountManagerService
}
private void purgeOldGrants(UserAccounts accounts) {
- synchronized (accounts.cacheLock) {
- List<Integer> uids = accounts.accountsDb.findAllUidGrants();
- for (int uid : uids) {
- final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
- if (packageExists) {
- continue;
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ List<Integer> uids = accounts.accountsDb.findAllUidGrants();
+ for (int uid : uids) {
+ final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
+ if (packageExists) {
+ continue;
+ }
+ Log.d(TAG, "deleting grants for UID " + uid
+ + " because its package is no longer installed");
+ accounts.accountsDb.deleteGrantsByUid(uid);
}
- Log.d(TAG, "deleting grants for UID " + uid
- + " because its package is no longer installed");
- accounts.accountsDb.deleteGrantsByUid(uid);
}
}
}
private void removeVisibilityValuesForPackage(String packageName) {
+ if (isSpecialPackageKey(packageName)) {
+ return;
+ }
synchronized (mUsers) {
- for (int i = 0; i < mUsers.size(); i++) {
- UserAccounts accounts = mUsers.valueAt(i);
- try {
- int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
- } catch (NameNotFoundException e) {
- // package does not exist - remove visibility values
- accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+ int numberOfUsers = mUsers.size();
+ for (int i = 0; i < numberOfUsers; i++) {
+ UserAccounts accounts = mUsers.valueAt(i);
+ try {
+ mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
+ } catch (NameNotFoundException e) {
+ // package does not exist - remove visibility values
+ accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ for (Account account : accounts.visibilityCache.keySet()) {
+ Map<String, Integer> accountVisibility =
+ getPackagesAndVisibilityForAccountLocked(account, accounts);
+ accountVisibility.remove(packageName);
+ }
+ }
+ }
}
}
}
}
+
private void onCleanupUser(int userId) {
Log.i(TAG, "onCleanupUser " + userId);
UserAccounts accounts;
@@ -1203,8 +1254,10 @@ public class AccountManagerService
mLocalUnlockedUsers.delete(userId);
}
if (accounts != null) {
- synchronized (accounts.cacheLock) {
- accounts.accountsDb.close();
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ accounts.accountsDb.close();
+ }
}
}
}
@@ -1284,8 +1337,11 @@ public class AccountManagerService
return null;
}
- synchronized (accounts.cacheLock) {
- return accounts.accountsDb.findAccountPasswordByNameAndType(account.name, account.type);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ return accounts.accountsDb
+ .findAccountPasswordByNameAndType(account.name, account.type);
+ }
}
}
@@ -1311,15 +1367,17 @@ public class AccountManagerService
if (account == null) {
return null;
}
- synchronized (accounts.cacheLock) {
- AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account);
- if (previousNameRef == null) {
- String previousName = accounts.accountsDb.findDeAccountPreviousName(account);
- previousNameRef = new AtomicReference<>(previousName);
- accounts.previousNameCache.put(account, previousNameRef);
- return previousName;
- } else {
- return previousNameRef.get();
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account);
+ if (previousNameRef == null) {
+ String previousName = accounts.accountsDb.findDeAccountPreviousName(account);
+ previousNameRef = new AtomicReference<>(previousName);
+ accounts.previousNameCache.put(account, previousNameRef);
+ return previousName;
+ } else {
+ return previousNameRef.get();
+ }
}
}
}
@@ -1349,11 +1407,13 @@ public class AccountManagerService
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
- if (!accountExistsCacheLocked(accounts, account)) {
- return null;
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ if (!accountExistsCacheLocked(accounts, account)) {
+ return null;
+ }
+ return readUserDataInternalLocked(accounts, account, key);
}
- return readUserDataInternalLocked(accounts, account, key);
}
} finally {
restoreCallingIdentity(identityToken);
@@ -1512,8 +1572,10 @@ public class AccountManagerService
private boolean updateLastAuthenticatedTime(Account account) {
final UserAccounts accounts = getUserAccountsForCaller();
- synchronized (accounts.cacheLock) {
- return accounts.accountsDb.updateAccountLastAuthenticatedTime(account);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ return accounts.accountsDb.updateAccountLastAuthenticatedTime(account);
+ }
}
}
@@ -1536,13 +1598,15 @@ public class AccountManagerService
public void run() throws RemoteException {
// Confirm that the owner's account still exists before this step.
UserAccounts owner = getUserAccounts(parentUserId);
- synchronized (owner.cacheLock) {
- for (Account acc : getAccounts(parentUserId,
- mContext.getOpPackageName())) {
- if (acc.equals(account)) {
- mAuthenticator.addAccountFromCredentials(
- this, account, accountCredentials);
- break;
+ synchronized (owner.dbLock) {
+ synchronized (owner.cacheLock) {
+ for (Account acc : getAccounts(parentUserId,
+ mContext.getOpPackageName())) {
+ if (acc.equals(account)) {
+ mAuthenticator.addAccountFromCredentials(
+ this, account, accountCredentials);
+ break;
+ }
}
}
}
@@ -1583,51 +1647,55 @@ public class AccountManagerService
+ " is locked. callingUid=" + callingUid);
return false;
}
- synchronized (accounts.cacheLock) {
- accounts.accountsDb.beginTransaction();
- try {
- if (accounts.accountsDb.findCeAccountId(account) >= 0) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping since the account already exists");
- return false;
- }
- long accountId = accounts.accountsDb.insertCeAccount(account, password);
- if (accountId < 0) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping the DB insert failed");
- return false;
- }
- // Insert into DE table
- if (accounts.accountsDb.insertDeAccount(account, accountId) < 0) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping the DB insert failed");
- return false;
- }
- if (extras != null) {
- for (String key : extras.keySet()) {
- final String value = extras.getString(key);
- if (accounts.accountsDb.insertExtra(accountId, key, value) < 0) {
- Log.w(TAG, "insertAccountIntoDatabase: " + account
- + ", skipping since insertExtra failed for key " + key);
- return false;
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ accounts.accountsDb.beginTransaction();
+ try {
+ if (accounts.accountsDb.findCeAccountId(account) >= 0) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping since the account already exists");
+ return false;
+ }
+ long accountId = accounts.accountsDb.insertCeAccount(account, password);
+ if (accountId < 0) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping the DB insert failed");
+ return false;
+ }
+ // Insert into DE table
+ if (accounts.accountsDb.insertDeAccount(account, accountId) < 0) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping the DB insert failed");
+ return false;
+ }
+ if (extras != null) {
+ for (String key : extras.keySet()) {
+ final String value = extras.getString(key);
+ if (accounts.accountsDb.insertExtra(accountId, key, value) < 0) {
+ Log.w(TAG, "insertAccountIntoDatabase: " + account
+ + ", skipping since insertExtra failed for key " + key);
+ return false;
+ }
}
}
- }
- if (packageToVisibility != null) {
- for (Entry<String, Integer> entry : packageToVisibility.entrySet()) {
- setAccountVisibility(account, entry.getKey() /* package */,
- entry.getValue() /* visibility */, false /* notify */, accounts);
+ if (packageToVisibility != null) {
+ for (Entry<String, Integer> entry : packageToVisibility.entrySet()) {
+ setAccountVisibility(account, entry.getKey() /* package */,
+ entry.getValue() /* visibility */, false /* notify */,
+ accounts);
+ }
}
- }
- accounts.accountsDb.setTransactionSuccessful();
+ accounts.accountsDb.setTransactionSuccessful();
- logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS, accountId,
- accounts, callingUid);
+ logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS,
+ accountId,
+ accounts, callingUid);
- insertAccountIntoCacheLocked(accounts, account);
- } finally {
- accounts.accountsDb.endTransaction();
+ insertAccountIntoCacheLocked(accounts, account);
+ } finally {
+ accounts.accountsDb.endTransaction();
+ }
}
}
if (getUserManager().getUserInfo(accounts.userId).canHaveProfile()) {
@@ -1812,72 +1880,76 @@ public class AccountManagerService
}
}
}
- synchronized (accounts.cacheLock) {
- accounts.accountsDb.beginTransaction();
- Account renamedAccount = new Account(newName, accountToRename.type);
- if ((accounts.accountsDb.findCeAccountId(renamedAccount) >= 0)) {
- Log.e(TAG, "renameAccount failed - account with new name already exists");
- return null;
- }
- try {
- final long accountId = accounts.accountsDb.findDeAccountId(accountToRename);
- if (accountId >= 0) {
- accounts.accountsDb.renameCeAccount(accountId, newName);
- if (accounts.accountsDb.renameDeAccount(
- accountId, newName, accountToRename.name)) {
- accounts.accountsDb.setTransactionSuccessful();
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ accounts.accountsDb.beginTransaction();
+ Account renamedAccount = new Account(newName, accountToRename.type);
+ if ((accounts.accountsDb.findCeAccountId(renamedAccount) >= 0)) {
+ Log.e(TAG, "renameAccount failed - account with new name already exists");
+ return null;
+ }
+ try {
+ final long accountId = accounts.accountsDb.findDeAccountId(accountToRename);
+ if (accountId >= 0) {
+ accounts.accountsDb.renameCeAccount(accountId, newName);
+ if (accounts.accountsDb.renameDeAccount(
+ accountId, newName, accountToRename.name)) {
+ accounts.accountsDb.setTransactionSuccessful();
+ } else {
+ Log.e(TAG, "renameAccount failed");
+ return null;
+ }
} else {
- Log.e(TAG, "renameAccount failed");
+ Log.e(TAG, "renameAccount failed - old account does not exist");
return null;
}
- } else {
- Log.e(TAG, "renameAccount failed - old account does not exist");
- return null;
+ } finally {
+ accounts.accountsDb.endTransaction();
}
- } finally {
- accounts.accountsDb.endTransaction();
- }
/*
* Database transaction was successful. Clean up cached
* data associated with the account in the user profile.
*/
- renamedAccount = insertAccountIntoCacheLocked(accounts, renamedAccount);
+ renamedAccount = insertAccountIntoCacheLocked(accounts, renamedAccount);
/*
* Extract the data and token caches before removing the
* old account to preserve the user data associated with
* the account.
*/
- Map<String, String> tmpData = accounts.userDataCache.get(accountToRename);
- Map<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
- removeAccountFromCacheLocked(accounts, accountToRename);
+ Map<String, String> tmpData = accounts.userDataCache.get(accountToRename);
+ Map<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
+ Map<String, Integer> tmpVisibility = accounts.visibilityCache.get(accountToRename);
+ removeAccountFromCacheLocked(accounts, accountToRename);
/*
* Update the cached data associated with the renamed
* account.
*/
- accounts.userDataCache.put(renamedAccount, tmpData);
- accounts.authTokenCache.put(renamedAccount, tmpTokens);
- accounts.previousNameCache.put(
- renamedAccount,
- new AtomicReference<>(accountToRename.name));
- resultAccount = renamedAccount;
-
- int parentUserId = accounts.userId;
- if (canHaveProfile(parentUserId)) {
+ accounts.userDataCache.put(renamedAccount, tmpData);
+ accounts.authTokenCache.put(renamedAccount, tmpTokens);
+ accounts.visibilityCache.put(renamedAccount, tmpVisibility);
+ accounts.previousNameCache.put(
+ renamedAccount,
+ new AtomicReference<>(accountToRename.name));
+ resultAccount = renamedAccount;
+
+ int parentUserId = accounts.userId;
+ if (canHaveProfile(parentUserId)) {
/*
* Owner or system user account was renamed, rename the account for
* those users with which the account was shared.
*/
- List<UserInfo> users = getUserManager().getUsers(true);
- for (UserInfo user : users) {
- if (user.isRestricted()
- && (user.restrictedProfileParentId == parentUserId)) {
- renameSharedAccountAsUser(accountToRename, newName, user.id);
+ List<UserInfo> users = getUserManager().getUsers(true);
+ for (UserInfo user : users) {
+ if (user.isRestricted()
+ && (user.restrictedProfileParentId == parentUserId)) {
+ renameSharedAccountAsUser(accountToRename, newName, user.id);
+ }
}
}
- }
- sendNotificationAccountUpdated(resultAccount, accounts);
- sendAccountsChangedBroadcast(accounts.userId);
+ sendNotificationAccountUpdated(resultAccount, accounts);
+ sendAccountsChangedBroadcast(accounts.userId);
+ }
}
return resultAccount;
}
@@ -2075,42 +2147,47 @@ public class AccountManagerService
Slog.i(TAG, "Removing account " + account + " while user "+ accounts.userId
+ " is still locked. CE data will be removed later");
}
- synchronized (accounts.cacheLock) {
- Map<String, Integer> packagesToVisibility = getRequestingPackages(account, accounts);
- accounts.accountsDb.beginTransaction();
- // Set to a dummy value, this will only be used if the database
- // transaction succeeds.
- long accountId = -1;
- try {
- accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId >= 0) {
- isChanged = accounts.accountsDb.deleteDeAccount(accountId);
- }
- // always delete from CE table if CE storage is available
- // DE account could be removed while CE was locked
- if (userUnlocked) {
- long ceAccountId = accounts.accountsDb.findCeAccountId(account);
- if (ceAccountId >= 0) {
- accounts.accountsDb.deleteCeAccount(ceAccountId);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ Map<String, Integer> packagesToVisibility = getRequestingPackages(account,
+ accounts);
+ accounts.accountsDb.beginTransaction();
+ // Set to a dummy value, this will only be used if the database
+ // transaction succeeds.
+ long accountId = -1;
+ try {
+ accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId >= 0) {
+ isChanged = accounts.accountsDb.deleteDeAccount(accountId);
}
- }
- accounts.accountsDb.setTransactionSuccessful();
- } finally {
- accounts.accountsDb.endTransaction();
- }
- if (isChanged) {
- removeAccountFromCacheLocked(accounts, account);
- for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) {
- if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) {
- notifyPackage(packageToVisibility.getKey(), accounts);
+ // always delete from CE table if CE storage is available
+ // DE account could be removed while CE was locked
+ if (userUnlocked) {
+ long ceAccountId = accounts.accountsDb.findCeAccountId(account);
+ if (ceAccountId >= 0) {
+ accounts.accountsDb.deleteCeAccount(ceAccountId);
+ }
}
+ accounts.accountsDb.setTransactionSuccessful();
+ } finally {
+ accounts.accountsDb.endTransaction();
}
+ if (isChanged) {
+ removeAccountFromCacheLocked(accounts, account);
+ for (Entry<String, Integer> packageToVisibility : packagesToVisibility
+ .entrySet()) {
+ if (packageToVisibility.getValue()
+ != AccountManager.VISIBILITY_NOT_VISIBLE) {
+ notifyPackage(packageToVisibility.getKey(), accounts);
+ }
+ }
- // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred.
- sendAccountsChangedBroadcast(accounts.userId);
- String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE
- : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE;
- logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts);
+ // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred.
+ sendAccountsChangedBroadcast(accounts.userId);
+ String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE
+ : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE;
+ logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts);
+ }
}
}
long id = Binder.clearCallingIdentity();
@@ -2160,53 +2237,48 @@ public class AccountManagerService
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
+ List<Pair<Account, String>> deletedTokens;
+ synchronized (accounts.dbLock) {
accounts.accountsDb.beginTransaction();
try {
- invalidateAuthTokenLocked(accounts, accountType, authToken);
- invalidateCustomTokenLocked(accounts, accountType, authToken);
+ deletedTokens = invalidateAuthTokenLocked(accounts, accountType, authToken);
accounts.accountsDb.setTransactionSuccessful();
} finally {
accounts.accountsDb.endTransaction();
}
+ synchronized (accounts.cacheLock) {
+ for (Pair<Account, String> tokenInfo : deletedTokens) {
+ Account act = tokenInfo.first;
+ String tokenType = tokenInfo.second;
+ writeAuthTokenIntoCacheLocked(accounts, act, tokenType, null);
+ }
+ // wipe out cached token in memory.
+ accounts.accountTokenCaches.remove(accountType, authToken);
+ }
}
} finally {
restoreCallingIdentity(identityToken);
}
}
- private void invalidateCustomTokenLocked(
- UserAccounts accounts,
- String accountType,
- String authToken) {
- if (authToken == null || accountType == null) {
- return;
- }
- // Also wipe out cached token in memory.
- accounts.accountTokenCaches.remove(accountType, authToken);
- }
-
- private void invalidateAuthTokenLocked(UserAccounts accounts, String accountType,
+ private List<Pair<Account, String>> invalidateAuthTokenLocked(UserAccounts accounts, String accountType,
String authToken) {
- if (authToken == null || accountType == null) {
- return;
- }
+ // TODO Move to AccountsDB
+ List<Pair<Account, String>> results = new ArrayList<>();
Cursor cursor = accounts.accountsDb.findAuthtokenForAllAccounts(accountType, authToken);
+
try {
while (cursor.moveToNext()) {
String authTokenId = cursor.getString(0);
String accountName = cursor.getString(1);
String authTokenType = cursor.getString(2);
accounts.accountsDb.deleteAuthToken(authTokenId);
- writeAuthTokenIntoCacheLocked(
- accounts,
- new Account(accountName, accountType),
- authTokenType,
- null);
+ results.add(Pair.create(new Account(accountName, accountType), authTokenType));
}
} finally {
cursor.close();
}
+ return results;
}
private void saveCachedToken(
@@ -2236,8 +2308,9 @@ public class AccountManagerService
}
cancelNotification(getSigninRequiredNotificationId(accounts, account),
UserHandle.of(accounts.userId));
- synchronized (accounts.cacheLock) {
+ synchronized (accounts.dbLock) {
accounts.accountsDb.beginTransaction();
+ boolean updateCache = false;
try {
long accountId = accounts.accountsDb.findDeAccountId(account);
if (accountId < 0) {
@@ -2246,12 +2319,17 @@ public class AccountManagerService
accounts.accountsDb.deleteAuthtokensByAccountIdAndType(accountId, type);
if (accounts.accountsDb.insertAuthToken(accountId, type, authToken) >= 0) {
accounts.accountsDb.setTransactionSuccessful();
- writeAuthTokenIntoCacheLocked(accounts, account, type, authToken);
+ updateCache = true;
return true;
}
return false;
} finally {
accounts.accountsDb.endTransaction();
+ if (updateCache) {
+ synchronized (accounts.cacheLock) {
+ writeAuthTokenIntoCacheLocked(accounts, account, type, authToken);
+ }
+ }
}
}
}
@@ -2349,31 +2427,35 @@ public class AccountManagerService
return;
}
boolean isChanged = false;
- synchronized (accounts.cacheLock) {
- accounts.accountsDb.beginTransaction();
- try {
- final long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId >= 0) {
- accounts.accountsDb.updateCeAccountPassword(accountId, password);
- accounts.accountsDb.deleteAuthTokensByAccountId(accountId);
- accounts.authTokenCache.remove(account);
- accounts.accountTokenCaches.remove(account);
- accounts.accountsDb.setTransactionSuccessful();
- // If there is an account whose password will be updated and the database
- // transactions succeed, then we say that a change has occured. Even if the
- // new password is the same as the old and there were no authtokens to delete.
- isChanged = true;
- String action = (password == null || password.length() == 0) ?
- AccountsDb.DEBUG_ACTION_CLEAR_PASSWORD
- : AccountsDb.DEBUG_ACTION_SET_PASSWORD;
- logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts, callingUid);
- }
- } finally {
- accounts.accountsDb.endTransaction();
- if (isChanged) {
- // Send LOGIN_ACCOUNTS_CHANGED only if the something changed.
- sendNotificationAccountUpdated(account, accounts);
- sendAccountsChangedBroadcast(accounts.userId);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ accounts.accountsDb.beginTransaction();
+ try {
+ final long accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId >= 0) {
+ accounts.accountsDb.updateCeAccountPassword(accountId, password);
+ accounts.accountsDb.deleteAuthTokensByAccountId(accountId);
+ accounts.authTokenCache.remove(account);
+ accounts.accountTokenCaches.remove(account);
+ accounts.accountsDb.setTransactionSuccessful();
+ // If there is an account whose password will be updated and the database
+ // transactions succeed, then we say that a change has occured. Even if the
+ // new password is the same as the old and there were no authtokens to
+ // delete.
+ isChanged = true;
+ String action = (password == null || password.length() == 0) ?
+ AccountsDb.DEBUG_ACTION_CLEAR_PASSWORD
+ : AccountsDb.DEBUG_ACTION_SET_PASSWORD;
+ logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts,
+ callingUid);
+ }
+ } finally {
+ accounts.accountsDb.endTransaction();
+ if (isChanged) {
+ // Send LOGIN_ACCOUNTS_CHANGED only if the something changed.
+ sendNotificationAccountUpdated(account, accounts);
+ sendAccountsChangedBroadcast(accounts.userId);
+ }
}
}
}
@@ -2427,11 +2509,13 @@ public class AccountManagerService
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
- if (!accountExistsCacheLocked(accounts, account)) {
- return;
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ if (!accountExistsCacheLocked(accounts, account)) {
+ return;
+ }
+ setUserdataInternalLocked(accounts, account, key, value);
}
- setUserdataInternalLocked(accounts, account, key, value);
}
} finally {
restoreCallingIdentity(identityToken);
@@ -3855,10 +3939,8 @@ public class AccountManagerService
@Override
public void run() throws RemoteException {
- synchronized (mAccounts.cacheLock) {
- mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid,
- mPackageName, false /* include managed not visible*/);
- }
+ mAccountsOfType = getAccountsFromCache(mAccounts, mAccountType,
+ mCallingUid, mPackageName, false /* include managed not visible*/);
// check whether each account matches the requested features
mAccountsWithFeatures = new ArrayList<>(mAccountsOfType.length);
mCurrentAccount = 0;
@@ -4002,16 +4084,14 @@ public class AccountManagerService
for (int userId : userIds) {
UserAccounts userAccounts = getUserAccounts(userId);
if (userAccounts == null) continue;
- synchronized (userAccounts.cacheLock) {
- Account[] accounts = getAccountsFromCacheLocked(
- userAccounts,
- null /* type */,
- Binder.getCallingUid(),
- null /* packageName */,
- false /* include managed not visible*/);
- for (int a = 0; a < accounts.length; a++) {
- runningAccounts.add(new AccountAndUser(accounts[a], userId));
- }
+ Account[] accounts = getAccountsFromCache(
+ userAccounts,
+ null /* type */,
+ Binder.getCallingUid(),
+ null /* packageName */,
+ false /* include managed not visible*/);
+ for (Account account : accounts) {
+ runningAccounts.add(new AccountAndUser(account, userId));
}
}
@@ -4097,22 +4177,20 @@ public class AccountManagerService
String callingPackage,
List<String> visibleAccountTypes,
boolean includeUserManagedNotVisible) {
- synchronized (userAccounts.cacheLock) {
- ArrayList<Account> visibleAccounts = new ArrayList<>();
- for (String visibleType : visibleAccountTypes) {
- Account[] accountsForType = getAccountsFromCacheLocked(
- userAccounts, visibleType, callingUid, callingPackage,
- includeUserManagedNotVisible);
- if (accountsForType != null) {
- visibleAccounts.addAll(Arrays.asList(accountsForType));
- }
- }
- Account[] result = new Account[visibleAccounts.size()];
- for (int i = 0; i < visibleAccounts.size(); i++) {
- result[i] = visibleAccounts.get(i);
+ ArrayList<Account> visibleAccounts = new ArrayList<>();
+ for (String visibleType : visibleAccountTypes) {
+ Account[] accountsForType = getAccountsFromCache(
+ userAccounts, visibleType, callingUid, callingPackage,
+ includeUserManagedNotVisible);
+ if (accountsForType != null) {
+ visibleAccounts.addAll(Arrays.asList(accountsForType));
}
- return result;
}
+ Account[] result = new Account[visibleAccounts.size()];
+ for (int i = 0; i < visibleAccounts.size(); i++) {
+ result[i] = visibleAccounts.get(i);
+ }
+ return result;
}
@Override
@@ -4178,10 +4256,12 @@ public class AccountManagerService
public Account[] getSharedAccountsAsUser(int userId) {
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
- List<Account> accountList = accounts.accountsDb.getSharedAccounts();
- Account[] accountArray = new Account[accountList.size()];
- accountList.toArray(accountArray);
- return accountArray;
+ synchronized (accounts.dbLock) {
+ List<Account> accountList = accounts.accountsDb.getSharedAccounts();
+ Account[] accountArray = new Account[accountList.size()];
+ accountList.toArray(accountArray);
+ return accountArray;
+ }
}
@Override
@@ -4261,11 +4341,8 @@ public class AccountManagerService
try {
UserAccounts userAccounts = getUserAccounts(userId);
if (features == null || features.length == 0) {
- Account[] accounts;
- synchronized (userAccounts.cacheLock) {
- accounts = getAccountsFromCacheLocked(
- userAccounts, type, callingUid, opPackageName, false);
- }
+ Account[] accounts = getAccountsFromCache(userAccounts, type, callingUid,
+ opPackageName, false);
Bundle result = new Bundle();
result.putParcelableArray(AccountManager.KEY_ACCOUNTS, accounts);
onResult(response, result);
@@ -4821,33 +4898,36 @@ public class AccountManagerService
private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout,
String[] args, boolean isCheckinRequest) {
- synchronized (userAccounts.cacheLock) {
- if (isCheckinRequest) {
- // This is a checkin request. *Only* upload the account types and the count of each.
+ if (isCheckinRequest) {
+ // This is a checkin request. *Only* upload the account types and the count of
+ // each.
+ synchronized (userAccounts.dbLock) {
userAccounts.accountsDb.dumpDeAccountsTable(fout);
- } else {
- Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
- Process.SYSTEM_UID, null /* packageName */, false);
- fout.println("Accounts: " + accounts.length);
- for (Account account : accounts) {
- fout.println(" " + account);
- }
+ }
+ } else {
+ Account[] accounts = getAccountsFromCache(userAccounts, null /* type */,
+ Process.SYSTEM_UID, null /* packageName */, false);
+ fout.println("Accounts: " + accounts.length);
+ for (Account account : accounts) {
+ fout.println(" " + account);
+ }
- // Add debug information.
- fout.println();
+ // Add debug information.
+ fout.println();
+ synchronized (userAccounts.dbLock) {
userAccounts.accountsDb.dumpDebugTable(fout);
- fout.println();
- synchronized (mSessions) {
- final long now = SystemClock.elapsedRealtime();
- fout.println("Active Sessions: " + mSessions.size());
- for (Session session : mSessions.values()) {
- fout.println(" " + session.toDebugString(now));
- }
+ }
+ fout.println();
+ synchronized (mSessions) {
+ final long now = SystemClock.elapsedRealtime();
+ fout.println("Active Sessions: " + mSessions.size());
+ for (Session session : mSessions.values()) {
+ fout.println(" " + session.toDebugString(now));
}
-
- fout.println();
- mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId);
}
+
+ fout.println();
+ mAuthenticatorCache.dump(fd, fout, args, userAccounts.userId);
}
}
@@ -5160,26 +5240,28 @@ public class AccountManagerService
return true;
}
UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callerUid));
- synchronized (accounts.cacheLock) {
- long grantsCount;
- if (authTokenType != null) {
- grantsCount = accounts.accountsDb.findMatchingGrantsCount(callerUid, authTokenType,
- account);
- } else {
- grantsCount = accounts.accountsDb.findMatchingGrantsCountAnyToken(callerUid,
- account);
- }
- final boolean permissionGranted = grantsCount > 0;
-
- if (!permissionGranted && ActivityManager.isRunningInTestHarness()) {
- // TODO: Skip this check when running automated tests. Replace this
- // with a more general solution.
- Log.d(TAG, "no credentials permission for usage of " + account + ", "
- + authTokenType + " by uid " + callerUid
- + " but ignoring since device is in test harness.");
- return true;
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ long grantsCount;
+ if (authTokenType != null) {
+ grantsCount = accounts.accountsDb
+ .findMatchingGrantsCount(callerUid, authTokenType, account);
+ } else {
+ grantsCount = accounts.accountsDb.findMatchingGrantsCountAnyToken(callerUid,
+ account);
+ }
+ final boolean permissionGranted = grantsCount > 0;
+
+ if (!permissionGranted && ActivityManager.isRunningInTestHarness()) {
+ // TODO: Skip this check when running automated tests. Replace this
+ // with a more general solution.
+ Log.d(TAG, "no credentials permission for usage of " + account + ", "
+ + authTokenType + " by uid " + callerUid
+ + " but ignoring since device is in test harness.");
+ return true;
+ }
+ return permissionGranted;
}
- return permissionGranted;
}
}
@@ -5293,15 +5375,18 @@ public class AccountManagerService
return;
}
UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
- synchronized (accounts.cacheLock) {
- long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId >= 0) {
- accounts.accountsDb.insertGrant(accountId, authTokenType, uid);
- }
- cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid),
- UserHandle.of(accounts.userId));
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ long accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId >= 0) {
+ accounts.accountsDb.insertGrant(accountId, authTokenType, uid);
+ }
+ cancelNotification(
+ getCredentialPermissionNotificationId(account, authTokenType, uid),
+ UserHandle.of(accounts.userId));
- cancelAccountAccessRequestNotificationIfNeeded(account, uid, true);
+ cancelAccountAccessRequestNotificationIfNeeded(account, uid, true);
+ }
}
// Listeners are a final CopyOnWriteArrayList, hence no lock needed.
@@ -5325,21 +5410,24 @@ public class AccountManagerService
return;
}
UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
- synchronized (accounts.cacheLock) {
- accounts.accountsDb.beginTransaction();
- try {
- long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId >= 0) {
- accounts.accountsDb.deleteGrantsByAccountIdAuthTokenTypeAndUid(
- accountId, authTokenType, uid);
- accounts.accountsDb.setTransactionSuccessful();
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ accounts.accountsDb.beginTransaction();
+ try {
+ long accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId >= 0) {
+ accounts.accountsDb.deleteGrantsByAccountIdAuthTokenTypeAndUid(
+ accountId, authTokenType, uid);
+ accounts.accountsDb.setTransactionSuccessful();
+ }
+ } finally {
+ accounts.accountsDb.endTransaction();
}
- } finally {
- accounts.accountsDb.endTransaction();
- }
- cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid),
- new UserHandle(accounts.userId));
+ cancelNotification(
+ getCredentialPermissionNotificationId(account, authTokenType, uid),
+ UserHandle.of(accounts.userId));
+ }
}
// Listeners are a final CopyOnWriteArrayList, hence no lock needed.
@@ -5369,6 +5457,7 @@ public class AccountManagerService
accounts.userDataCache.remove(account);
accounts.authTokenCache.remove(account);
accounts.previousNameCache.remove(account);
+ accounts.visibilityCache.remove(account);
}
/**
@@ -5496,12 +5585,20 @@ public class AccountManagerService
/*
* packageName can be null. If not null, it should be used to filter out restricted accounts
* that the package is not allowed to access.
+ *
+ * <p>The method shouldn't be called with UserAccounts#cacheLock held, otherwise it will cause a
+ * deadlock
*/
@NonNull
- protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType,
+ protected Account[] getAccountsFromCache(UserAccounts userAccounts, String accountType,
int callingUid, @Nullable String callingPackage, boolean includeManagedNotVisible) {
+ Preconditions.checkState(!Thread.holdsLock(userAccounts.cacheLock),
+ "Method should not be called with cacheLock");
if (accountType != null) {
- final Account[] accounts = userAccounts.accountCache.get(accountType);
+ Account[] accounts;
+ synchronized (userAccounts.cacheLock) {
+ accounts = userAccounts.accountCache.get(accountType);
+ }
if (accounts == null) {
return EMPTY_ACCOUNT_ARRAY;
} else {
@@ -5510,20 +5607,23 @@ public class AccountManagerService
}
} else {
int totalLength = 0;
- for (Account[] accounts : userAccounts.accountCache.values()) {
- totalLength += accounts.length;
- }
- if (totalLength == 0) {
- return EMPTY_ACCOUNT_ARRAY;
- }
- Account[] accounts = new Account[totalLength];
- totalLength = 0;
- for (Account[] accountsOfType : userAccounts.accountCache.values()) {
- System.arraycopy(accountsOfType, 0, accounts, totalLength,
- accountsOfType.length);
- totalLength += accountsOfType.length;
+ Account[] accountsArray;
+ synchronized (userAccounts.cacheLock) {
+ for (Account[] accounts : userAccounts.accountCache.values()) {
+ totalLength += accounts.length;
+ }
+ if (totalLength == 0) {
+ return EMPTY_ACCOUNT_ARRAY;
+ }
+ accountsArray = new Account[totalLength];
+ totalLength = 0;
+ for (Account[] accountsOfType : userAccounts.accountCache.values()) {
+ System.arraycopy(accountsOfType, 0, accountsArray, totalLength,
+ accountsOfType.length);
+ totalLength += accountsOfType.length;
+ }
}
- return filterAccounts(userAccounts, accounts, callingUid, callingPackage,
+ return filterAccounts(userAccounts, accountsArray, callingUid, callingPackage,
includeManagedNotVisible);
}
}
@@ -5548,12 +5648,15 @@ public class AccountManagerService
String tokenType,
String callingPackage,
byte[] pkgSigDigest) {
- synchronized (accounts.cacheLock) {
- return accounts.accountTokenCaches.get(
- account, tokenType, callingPackage, pkgSigDigest);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ return accounts.accountTokenCaches.get(
+ account, tokenType, callingPackage, pkgSigDigest);
+ }
}
}
+ /** protected by the {@code dbLock}, {@code cacheLock} */
protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts,
Account account, String key, String value) {
Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
@@ -5570,14 +5673,24 @@ public class AccountManagerService
protected String readAuthTokenInternal(UserAccounts accounts, Account account,
String authTokenType) {
+ // Fast path - check if account is already cached
synchronized (accounts.cacheLock) {
Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
- if (authTokensForAccount == null) {
- // need to populate the cache for this account
- authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account);
- accounts.authTokenCache.put(account, authTokensForAccount);
+ if (authTokensForAccount != null) {
+ return authTokensForAccount.get(authTokenType);
+ }
+ }
+ // If not cached yet - do slow path and sync with db if necessary
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
+ if (authTokensForAccount == null) {
+ // need to populate the cache for this account
+ authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account);
+ accounts.authTokenCache.put(account, authTokensForAccount);
+ }
+ return authTokensForAccount.get(authTokenType);
}
- return authTokensForAccount.get(authTokenType);
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 22543cb9e022..8ca7ea1768b9 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -909,7 +909,7 @@ class AccountsDb implements AutoCloseable {
}
Integer findAccountVisibility(Account account, String packageName) {
- SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+ SQLiteDatabase db = mDeDatabase.getReadableDatabase();
final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_PACKAGE + "=? ",
new String[] {account.name, account.type, packageName}, null, null, null);
@@ -924,7 +924,7 @@ class AccountsDb implements AutoCloseable {
}
Integer findAccountVisibility(long accountId, String packageName) {
- SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+ SQLiteDatabase db = mDeDatabase.getReadableDatabase();
final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_PACKAGE + "=? ",
new String[] {String.valueOf(accountId), packageName}, null, null, null);
@@ -972,6 +972,41 @@ class AccountsDb implements AutoCloseable {
return result;
}
+ /**
+ * Returns a map account -> (package -> visibility)
+ */
+ Map <Account, Map<String, Integer>> findAllVisibilityValues() {
+ SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+ Map<Account, Map<String, Integer>> result = new HashMap<>();
+ Cursor cursor = db.rawQuery(
+ "SELECT " + TABLE_VISIBILITY + "." + VISIBILITY_PACKAGE
+ + ", " + TABLE_VISIBILITY + "." + VISIBILITY_VALUE
+ + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
+ + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE
+ + " FROM " + TABLE_VISIBILITY
+ + " JOIN " + TABLE_ACCOUNTS
+ + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID
+ + " = " + TABLE_VISIBILITY + "." + VISIBILITY_ACCOUNTS_ID, null);
+ try {
+ while (cursor.moveToNext()) {
+ String packageName = cursor.getString(0);
+ Integer visibility = cursor.getInt(1);
+ String accountName = cursor.getString(2);
+ String accountType = cursor.getString(3);
+ Account account = new Account(accountName, accountType);
+ Map <String, Integer> accountVisibility = result.get(account);
+ if (accountVisibility == null) {
+ accountVisibility = new HashMap<>();
+ result.put(account, accountVisibility);
+ }
+ accountVisibility.put(packageName, visibility);
+ }
+ } finally {
+ cursor.close();
+ }
+ return result;
+ }
+
boolean deleteAccountVisibilityForPackage(String packageName) {
SQLiteDatabase db = mDeDatabase.getWritableDatabase();
return db.delete(TABLE_VISIBILITY, VISIBILITY_PACKAGE + "=? ",
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b4f8f61971f8..8b0665c6d312 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -17,7 +17,6 @@
package com.android.server.am;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static com.android.server.am.ActivityManagerDebugConfig.*;
import java.io.FileDescriptor;
@@ -96,6 +95,10 @@ public final class ActiveServices {
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
+ // How long the startForegroundService() grace period is to get around to
+ // calling startForeground() before we ANR + stop it.
+ static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000;
+
// How long a service needs to be running until restarting its process
// is no longer considered to be a relaunch of the service.
static final int SERVICE_RESTART_DURATION = 1*1000;
@@ -307,8 +310,8 @@ public final class ActiveServices {
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
- int id, Notification notification,
- int callingPid, int callingUid, String callingPackage, final int userId)
+ int id, Notification notification, int callingPid, int callingUid,
+ boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
@@ -345,8 +348,9 @@ public final class ActiveServices {
return null;
}
- // Non-null notification means this is a start directly into the foreground
- if (!r.startRequested && notification == null) {
+ // If this isn't a direct-to-foreground start, check our ability to kick off an
+ // arbitrary service
+ if (!r.startRequested && !fgRequired) {
final long token = Binder.clearCallingIdentity();
try {
// Before going further -- if this app is not allowed to start services in the
@@ -392,12 +396,13 @@ public final class ActiveServices {
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
+ r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
- if (!callerFg && r.app == null
+ if (!callerFg && !fgRequired && r.app == null
&& mAm.mUserController.hasStartedUserState(r.userId)) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
@@ -449,9 +454,9 @@ public final class ActiveServices {
Slog.v(TAG_SERVICE, sb.toString());
}
} else if (DEBUG_DELAYED_STARTS) {
- if (callerFg) {
+ if (callerFg || fgRequired) {
Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="
- + callingUid + " pid=" + callingPid + "): " + r);
+ + callingUid + " pid=" + callingPid + " fgRequired=" + fgRequired + "): " + r);
} else if (r.app != null) {
Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);
} else {
@@ -461,6 +466,7 @@ public final class ActiveServices {
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
+ // STOPSHIP deprecated; remove when NotificationManager.startServiceInForeground is retired
if (notification != null) {
setServiceForegroundInnerLocked(r, id, notification, 0);
}
@@ -540,7 +546,7 @@ public final class ActiveServices {
if (first) {
smap.rescheduleDelayedStartsLocked();
}
- } else if (callerFg) {
+ } else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
@@ -756,8 +762,17 @@ public final class ActiveServices {
}
}
}
+ if (r.fgRequired) {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Service called startForeground() as required: " + r);
+ }
+ r.fgRequired = false;
+ r.fgWaiting = false;
+ mAm.mHandler.removeMessages(
+ ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
+ }
if (r.foregroundId != id) {
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
r.foregroundId = id;
}
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -779,7 +794,7 @@ public final class ActiveServices {
}
}
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
@@ -792,7 +807,7 @@ public final class ActiveServices {
}
}
- private void cancelForegroudNotificationLocked(ServiceRecord r) {
+ private void cancelForegroundNotificationLocked(ServiceRecord r) {
if (r.foregroundId != 0) {
// First check to see if this app has any other active foreground services
// with the same notification ID. If so, we shouldn't actually cancel it,
@@ -1631,7 +1646,7 @@ public final class ActiveServices {
r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
}
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
mAm.mHandler.removeCallbacks(r.restarter);
mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
@@ -1718,7 +1733,9 @@ public final class ActiveServices {
return null;
}
- if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
+ if (DEBUG_SERVICE) {
+ Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent + " fg=" + r.fgRequired);
+ }
// We are now bringing the service up, so no longer in the
// restarting state.
@@ -1944,8 +1961,10 @@ public final class ActiveServices {
ServiceRecord.StartItem si = null;
try {
si = r.pendingStarts.remove(0);
- if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
- + r + " " + r.intent + " args=" + si.intent);
+ if (DEBUG_SERVICE) {
+ Slog.v(TAG_SERVICE, "Sending arguments to: "
+ + r + " " + r.intent + " args=" + si.intent);
+ }
if (si.intent == null && N > 1) {
// If somehow we got a dummy null intent in the middle,
// then skip it. DO NOT skip a null intent when it is
@@ -1966,6 +1985,19 @@ public final class ActiveServices {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app);
}
+ if (r.fgRequired && !r.fgWaiting) {
+ if (!r.isForeground) {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);
+ }
+ scheduleServiceForegroundTransitionTimeoutLocked(r);
+ } else {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Service already foreground; no new timeout: " + r);
+ }
+ r.fgRequired = false;
+ }
+ }
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
@@ -2101,7 +2133,7 @@ public final class ActiveServices {
}
}
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
@@ -2925,23 +2957,53 @@ public final class ActiveServices {
}
}
+ void serviceForegroundTimeout(ServiceRecord r) {
+ ProcessRecord app;
+ synchronized (mAm) {
+ if (!r.fgRequired) {
+ return;
+ }
+
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Service foreground-required timeout for " + r);
+ }
+ app = r.app;
+ r.fgWaiting = false;
+ stopServiceLocked(r);
+ }
+
+ if (app != null) {
+ mAm.mAppErrors.appNotResponding(app, null, null, false,
+ "Context.startForegroundService() did not then call Service.startForeground()");
+ }
+ }
+
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
- long now = SystemClock.uptimeMillis();
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
- mAm.mHandler.sendMessageAtTime(msg,
- proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
+ mAm.mHandler.sendMessageDelayed(msg,
+ proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
+ }
+
+ void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
+ if (r.app.executingServices.size() == 0 || r.app.thread == null) {
+ return;
+ }
+ Message msg = mAm.mHandler.obtainMessage(
+ ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
+ msg.obj = r;
+ r.fgWaiting = true;
+ mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
}
final class ServiceDumper {
private final FileDescriptor fd;
private final PrintWriter pw;
private final String[] args;
- private final int opti;
private final boolean dumpAll;
private final String dumpPackage;
private final ItemMatcher matcher;
@@ -2962,7 +3024,6 @@ public final class ActiveServices {
this.fd = fd;
this.pw = pw;
this.args = args;
- this.opti = opti;
this.dumpAll = dumpAll;
this.dumpPackage = dumpPackage;
matcher = new ItemMatcher();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 272fbf86aedd..b4da152a18ae 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1726,6 +1726,7 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
static final int NOTIFY_VR_SLEEPING_MSG = 65;
+ static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
static final int START_USER_SWITCH_FG_MSG = 712;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -1991,6 +1992,9 @@ public class ActivityManagerService extends IActivityManager.Stub
}
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
+ case SERVICE_FOREGROUND_TIMEOUT_MSG: {
+ mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
+ } break;
case UPDATE_TIME_ZONE: {
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -2743,6 +2747,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@VisibleForTesting
public ActivityManagerService(Injector injector) {
mInjector = injector;
+ mContext = mInjector.getContext();
GL_ES_VERSION = 0;
mActivityStarter = null;
mAppErrors = null;
@@ -3211,18 +3216,18 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
- mWindowManager.setFocusedApp(r.appToken, true);
-
- applyUpdateLockStateLocked(r);
- applyUpdateVrModeLocked(r);
if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
mHandler.obtainMessage(
FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
}
-
mLastResumedActivity = r;
+ mWindowManager.setFocusedApp(r.appToken, true);
+
+ applyUpdateLockStateLocked(r);
+ applyUpdateVrModeLocked(r);
+
EventLogTags.writeAmSetResumedActivity(
r == null ? -1 : r.userId,
r == null ? "NULL" : r.shortComponentName,
@@ -3928,8 +3933,13 @@ public class ActivityManagerService extends IActivityManager.Stub
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// Debuggable apps may include a wrapper script with their library directory.
String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
- if (new File(wrapperFileName).exists()) {
- invokeWith = "/system/bin/logwrapper " + wrapperFileName;
+ StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+ try {
+ if (new File(wrapperFileName).exists()) {
+ invokeWith = "/system/bin/logwrapper " + wrapperFileName;
+ }
+ } finally {
+ StrictMode.setThreadPolicy(oldPolicy);
}
}
@@ -6590,6 +6600,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+ getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
}
boolean willRestart = false;
if (app.persistent && !app.isolated) {
@@ -12083,6 +12094,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// the uid of the isolated process is specified by the caller.
uid = isolatedUid;
}
+ getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
// Register the isolated UID with this application so BatteryStats knows to
// attribute resource usage to the application.
@@ -17890,7 +17902,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int id, Notification notification,
+ String resolvedType, int id, Notification notification, boolean requireForeground,
String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
@@ -17904,28 +17916,28 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
- "startService: " + service + " type=" + resolvedType);
+ "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
- resolvedType, id, notification,
- callingPid, callingUid, callingPackage, userId);
+ resolvedType, id, notification, callingPid, callingUid,
+ requireForeground, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
- String callingPackage, int userId)
+ boolean fgRequired, String callingPackage, int userId)
throws TransactionTooLargeException {
synchronized(this) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(null, service,
- resolvedType, 0, null, -1, uid, callingPackage, userId);
+ resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
@@ -18276,6 +18288,10 @@ public class ActivityManagerService extends IActivityManager.Stub
return record.info.isInstantApp();
}
// Otherwise check with PackageManager.
+ if (callerPackage == null) {
+ Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
+ throw new IllegalArgumentException("Calling application did not provide package name");
+ }
mAppOpsService.checkPackage(uid, callerPackage);
try {
IPackageManager pm = AppGlobals.getPackageManager();
@@ -23589,6 +23605,21 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ /**
+ * Return the user id of the last resumed activity.
+ */
+ @Override
+ public @UserIdInt int getLastResumedActivityUserId() {
+ enforceCallingPermission(
+ permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
+ synchronized (this) {
+ if (mLastResumedActivity == null) {
+ return mUserController.getCurrentUserIdLocked();
+ }
+ return mLastResumedActivity.userId;
+ }
+ }
+
private final class SleepTokenImpl extends SleepToken {
private final String mTag;
private final long mAcquireTime;
@@ -23875,6 +23906,10 @@ public class ActivityManagerService extends IActivityManager.Stub
public static class Injector {
private NetworkManagementInternal mNmi;
+ public Context getContext() {
+ return null;
+ }
+
public AppOpsService getAppOpsService(File file, Handler handler) {
return new AppOpsService(file, handler);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index aaad12c1f289..a9bd87227929 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -82,6 +82,8 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
+
final class ActivityManagerShellCommand extends ShellCommand {
public static final String NO_CLASS_ERROR_CODE = "Error type 3";
private static final String SHELL_PACKAGE_NAME = "com.android.shell";
@@ -118,6 +120,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
private boolean mStreaming; // Streaming the profiling output to a file.
private int mDisplayId;
private int mStackId;
+ private int mTaskId;
+ private boolean mIsTaskOverlay;
final boolean mDumping;
@@ -263,6 +267,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
mUserId = defUser;
mDisplayId = INVALID_DISPLAY;
mStackId = INVALID_STACK_ID;
+ mTaskId = INVALID_TASK_ID;
+ mIsTaskOverlay = false;
return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
@Override
@@ -297,6 +303,10 @@ final class ActivityManagerShellCommand extends ShellCommand {
mDisplayId = Integer.parseInt(getNextArgRequired());
} else if (opt.equals("--stack")) {
mStackId = Integer.parseInt(getNextArgRequired());
+ } else if (opt.equals("--task")) {
+ mTaskId = Integer.parseInt(getNextArgRequired());
+ } else if (opt.equals("--task-overlay")) {
+ mIsTaskOverlay = true;
} else {
return false;
}
@@ -380,6 +390,14 @@ final class ActivityManagerShellCommand extends ShellCommand {
options = ActivityOptions.makeBasic();
options.setLaunchStackId(mStackId);
}
+ if (mTaskId != INVALID_TASK_ID) {
+ options = ActivityOptions.makeBasic();
+ options.setLaunchTaskId(mTaskId);
+
+ if (mIsTaskOverlay) {
+ options.setTaskOverlay(true, true /* canResume */);
+ }
+ }
if (mWaitOption) {
result = mInterface.startActivityAndWait(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
@@ -501,7 +519,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println("Starting service: " + intent);
pw.flush();
ComponentName cn = mInterface.startService(null, intent, intent.getType(),
- -1, null, SHELL_PACKAGE_NAME, mUserId);
+ -1, null, false, SHELL_PACKAGE_NAME, mUserId);
if (cn == null) {
err.println("Error: Not found; no service started.");
return -1;
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 04a09fe4305e..5edfb0651fe7 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -10,8 +10,8 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_ACTIVITY_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_IS_EPHEMERAL;
@@ -313,7 +313,7 @@ class ActivityMetricsLogger {
final LogMaker builder = new LogMaker(APP_TRANSITION);
builder.setPackageName(info.launchedActivity.packageName);
builder.setType(type);
- builder.addTaggedData(APP_TRANSITION_ACTIVITY_NAME, info.launchedActivity.info.name);
+ builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
if (info.launchedActivity.launchedFromPackage != null) {
builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
info.launchedActivity.launchedFromPackage);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 9a1cd8c3884b..2f61038bc230 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1820,14 +1820,22 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
}
@Override
- public boolean keyDispatchingTimedOut(String reason) {
+ public boolean keyDispatchingTimedOut(String reason, int windowPid) {
ActivityRecord anrActivity;
ProcessRecord anrApp;
+ boolean windowFromSameProcessAsActivity;
synchronized (service) {
anrActivity = getWaitingHistoryRecordLocked();
anrApp = app;
+ windowFromSameProcessAsActivity = app == null || app.pid == windowPid;
+ }
+ if (windowFromSameProcessAsActivity) {
+ return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
+ } else {
+ // In this case another process added windows using this activity token. So, we call the
+ // generic service input dispatch timed out method so that the right process is blamed.
+ return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0;
}
- return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
}
private ActivityRecord getWaitingHistoryRecordLocked() {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9a4f804cb1b3..498de63d11d8 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -67,7 +67,9 @@ import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
+import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_NONE;
@@ -121,7 +123,6 @@ import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import com.android.server.wm.StackWindowController;
import com.android.server.wm.StackWindowListener;
-import com.android.server.wm.TaskStack;
import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
@@ -759,6 +760,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
}
+ final void removeActivitiesFromLRUListLocked(TaskRecord task) {
+ for (ActivityRecord r : task.mActivities) {
+ mLRUActivities.remove(r);
+ }
+ }
+
final boolean updateLRUListLocked(ActivityRecord r) {
final boolean hadit = mLRUActivities.remove(r);
mLRUActivities.add(r);
@@ -1179,13 +1186,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
* @param resuming The activity we are currently trying to resume or null if this is not being
* called as part of resuming the top activity, so we shouldn't try to instigate
* a resume here if not null.
- * @param dontWait True if the caller does not want to wait for the pause to complete. If
- * set to true, we will immediately complete the pause here before returning.
+ * @param pauseImmediately True if the caller does not want to wait for the activity callback to
+ * complete pausing.
* @return Returns true if an activity now is in the PAUSING state, and we are waiting for
* it to tell us when it is done.
*/
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
- ActivityRecord resuming, boolean dontWait) {
+ ActivityRecord resuming, boolean pauseImmediately) {
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.state);
@@ -1207,7 +1214,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (mActivityContainer.mParentActivity == null) {
// Top level stack, not a child. Look for child stacks.
- mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
+ mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming,
+ pauseImmediately);
}
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
@@ -1237,7 +1245,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
prev.shortComponentName);
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
- userLeaving, prev.configChangeFlags, dontWait);
+ userLeaving, prev.configChangeFlags, pauseImmediately);
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
@@ -1268,7 +1276,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
}
- if (dontWait) {
+ if (pauseImmediately) {
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false, resuming);
@@ -3482,11 +3490,19 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
/**
+ * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
+ */
+ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
+ String reason, boolean oomAdj) {
+ return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
+ }
+
+ /**
* @return Returns true if this activity has been removed from the history
* list, or false if it is still in the list and will be removed later.
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
- String reason, boolean oomAdj) {
+ String reason, boolean oomAdj, boolean pauseImmediately) {
if (r.finishing) {
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
@@ -3523,9 +3539,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (mResumedActivity == r) {
if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare close transition: finishing " + r);
- if (endTask) {
- mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(task.taskId);
- }
+ if (endTask) {
+ mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(
+ task.taskId);
+ }
mWindowManager.prepareAppTransition(transit, false);
// Tell window manager to prepare for this one to be removed.
@@ -3535,7 +3552,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"finish() => pause with userLeaving=false");
- startPausingLocked(false, false, null, false);
+ startPausingLocked(false, false, null, pauseImmediately);
}
if (endTask) {
@@ -3546,15 +3563,30 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
// it is done pausing; else we can just directly finish it here.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
if (r.visible) {
- mWindowManager.prepareAppTransition(transit, false);
- r.setVisibility(false);
- mWindowManager.executeAppTransition();
- if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
- mStackSupervisor.mWaitingVisibleActivities.add(r);
+ prepareActivityHideTransitionAnimation(r, transit);
+ }
+
+ final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
+ : FINISH_AFTER_PAUSE;
+ final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj)
+ == null;
+
+ // The following code is an optimization. When the last non-task overlay activity
+ // is removed from the task, we remove the entire task from the stack. However,
+ // since that is done after the scheduled destroy callback from the activity, that
+ // call to change the visibility of the task overlay activities would be out of
+ // sync with the activitiy visibility being set for this finishing activity above.
+ // In this case, we can set the visibility of all the task overlay activities when
+ // we detect the last one is finishing to keep them in sync.
+ if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
+ for (ActivityRecord taskOverlay : task.mActivities) {
+ if (!taskOverlay.mTaskOverlay) {
+ continue;
+ }
+ prepareActivityHideTransitionAnimation(taskOverlay, transit);
}
}
- return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
- FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
+ return removedActivity;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
}
@@ -3565,6 +3597,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
}
+ private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) {
+ mWindowManager.prepareAppTransition(transit, false);
+ r.setVisibility(false);
+ mWindowManager.executeAppTransition();
+ if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
+ mStackSupervisor.mWaitingVisibleActivities.add(r);
+ }
+ }
+
static final int FINISH_IMMEDIATELY = 0;
static final int FINISH_AFTER_PAUSE = 1;
static final int FINISH_AFTER_VISIBLE = 2;
@@ -3858,15 +3899,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
r.removeWindowContainer();
final TaskRecord task = r.task;
final boolean lastActivity = task != null ? task.removeActivity(r) : false;
+ // If we are removing the last activity in the task, not including task overlay activities,
+ // then fall through into the block below to remove the entire task itself
+ final boolean onlyHasTaskOverlays = task != null
+ ? task.onlyHasTaskOverlayActivities(false /* excludingFinishing */) : false;
+
+ if (lastActivity || onlyHasTaskOverlays) {
+ if (DEBUG_STACK) {
+ Slog.i(TAG_STACK,
+ "removeActivityFromHistoryLocked: last activity removed from " + this
+ + " onlyHasTaskOverlays=" + onlyHasTaskOverlays);
+ }
- if (lastActivity) {
- if (DEBUG_STACK) Slog.i(TAG_STACK,
- "removeActivityFromHistoryLocked: last activity removed from " + this);
if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
task.isOverHomeStack()) {
mStackSupervisor.moveHomeStackTaskToTop(reason);
}
- removeTask(task, reason);
+ removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING);
}
cleanUpActivityServicesLocked(r);
r.removeUriPermissionsLocked();
@@ -4917,10 +4966,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
return starting;
}
- void removeTask(TaskRecord task, String reason) {
- removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING);
- }
-
/**
* Removes the input task from this stack.
* @param task to remove.
@@ -4930,6 +4975,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
*/
void removeTask(TaskRecord task, String reason, int mode) {
if (mode == REMOVE_TASK_MODE_DESTROYING) {
+ // When destroying a task, tell the supervisor to remove it so that any activity it has
+ // can be cleaned up correctly
+ mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
+ !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY);
task.removeWindowContainer();
}
@@ -4947,6 +4996,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
}
mTaskHistory.remove(task);
+ removeActivitiesFromLRUListLocked(task);
updateTaskMovement(task, true);
if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) {
@@ -5114,6 +5164,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
// Apps may depend on onResume()/onPause() being called in pairs.
if (setResume) {
mResumedActivity = r;
+ updateLRUListLocked(r);
}
// If the activity was previously pausing, then ensure we transfer that as well
if (setPause) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 27b8e91981c0..b623b2f2b180 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -254,6 +254,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// Used to indicate that a task is removed it should also be removed from recents.
static final boolean REMOVE_FROM_RECENTS = true;
+ // Used to indicate that pausing an activity should occur immediately without waiting for
+ // the activity callback indicating that it has completed pausing
+ static final boolean PAUSE_IMMEDIATELY = true;
+
/**
* The modes which affect which tasks are returned when calling
* {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}.
@@ -2536,18 +2540,28 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
/**
+ * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)}
+ */
+ boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) {
+ return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY);
+ }
+
+ /**
* Removes the task with the specified task id.
*
* @param taskId Identifier of the task to be removed.
* @param killProcess Kill any process associated with the task if possible.
* @param removeFromRecents Whether to also remove the task from recents.
+ * @param pauseImmediately Pauses all task activities immediately without waiting for the
+ * pause-complete callback from the activity.
* @return Returns true if the given task was found and removed.
*/
- boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) {
+ boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents,
+ boolean pauseImmediately) {
final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
INVALID_STACK_ID);
if (tr != null) {
- tr.removeTaskActivitiesLocked();
+ tr.removeTaskActivitiesLocked(pauseImmediately);
cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
if (tr.isPersistable) {
mService.notifyTaskPersisterLocked(null, true);
@@ -3555,8 +3569,16 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
stackHeader.append(" mFullscreen=" + stack.mFullscreen);
stackHeader.append("\n");
stackHeader.append(" mBounds=" + stack.mBounds);
- printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
- needSep, stackHeader.toString());
+
+ final boolean printedStackHeader = stack.dumpActivitiesLocked(fd, pw, dumpAll,
+ dumpClient, dumpPackage, needSep, stackHeader.toString());
+ printed |= printedStackHeader;
+ if (!printedStackHeader) {
+ // Ensure we always dump the stack header even if there are no activities
+ pw.println();
+ pw.println(stackHeader);
+ }
+
printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false,
!dumpAll, false, dumpPackage, true,
" Running activities (most recent first):", null);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 4bd06b76e92e..9258539f4268 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -640,6 +640,18 @@ class ActivityStarter {
final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
intent = new Intent(intent);
+ if (componentSpecified
+ && intent.getData() != null
+ && Intent.ACTION_VIEW.equals(intent.getAction())
+ && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
+ && mService.getPackageManagerInternalLocked()
+ .isInstantAppInstallerComponent(intent.getComponent())) {
+ // intercept intents targeted directly to the ephemeral installer the
+ // ephemeral installer should never be started with a raw URL; instead
+ // adjust the intent so it looks like a "normal" instant app launch
+ intent.setComponent(null /*component*/);
+ componentSpecified = false;
+ }
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
if (rInfo == null) {
@@ -1453,6 +1465,12 @@ class ActivityStarter {
return intentActivity;
}
+ /**
+ * Figure out which task and activity to bring to front when we have found an existing matching
+ * activity record in history. May also clear the task if needed.
+ * @param intentActivity Existing matching activity.
+ * @return {@link ActivityRecord} brought to front.
+ */
private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
mTargetStack = intentActivity.getStack();
mTargetStack.mLastPausedActivity = null;
@@ -1514,6 +1532,14 @@ class ActivityStarter {
"bringToFrontInsteadOfAdjacentLaunch");
}
mMovedToFront = true;
+ } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
+ // Target and computed stacks are on different displays and we've
+ // found a matching task - move the existing instance to that display and
+ // move it to front.
+ intentActivity.task.reparent(launchStack.mStackId, ON_TOP,
+ REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
+ "reparentToDisplay");
+ mMovedToFront = true;
}
mOptions = null;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 7b1af38da9ed..c10f77cefbe4 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -870,7 +870,7 @@ class AppErrors {
nativeProcs = NATIVE_STACKS_OF_INTEREST;
}
- int[] pids = Process.getPidsForCommands(nativeProcs);
+ int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
ArrayList<Integer> nativePids = null;
if (pids != null) {
diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java
index 8c18c462e956..0412db5e49c9 100644
--- a/services/core/java/com/android/server/am/LockTaskNotify.java
+++ b/services/core/java/com/android/server/am/LockTaskNotify.java
@@ -20,6 +20,8 @@ import android.app.ActivityManager;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemClock;
+import android.util.Slog;
import android.view.WindowManager;
import android.widget.Toast;
@@ -31,10 +33,12 @@ import com.android.internal.R;
*/
public class LockTaskNotify {
private static final String TAG = "LockTaskNotify";
+ private static final long SHOW_TOAST_MINIMUM_INTERVAL = 1000;
private final Context mContext;
private final H mHandler;
private Toast mLastToast;
+ private long mLastShowToastTime;
public LockTaskNotify(Context context) {
mContext = context;
@@ -55,10 +59,16 @@ public class LockTaskNotify {
if (text == null) {
return;
}
+ long showToastTime = SystemClock.elapsedRealtime();
+ if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) {
+ Slog.i(TAG, "Ignore toast since it is requested in very short interval.");
+ return;
+ }
if (mLastToast != null) {
mLastToast.cancel();
}
mLastToast = makeAllUserToastAndShow(text);
+ mLastShowToastTime = showToastTime;
}
public void show(boolean starting) {
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index c494171fbfbb..f05bfb6174d3 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -175,6 +175,8 @@ final class PendingIntentRecord extends IIntentSender.Stub {
return "broadcastIntent";
case ActivityManager.INTENT_SENDER_SERVICE:
return "startService";
+ case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
+ return "startForegroundService";
case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
return "activityResult";
}
@@ -318,9 +320,11 @@ final class PendingIntentRecord extends IIntentSender.Stub {
}
break;
case ActivityManager.INTENT_SENDER_SERVICE:
+ case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
try {
- owner.startServiceInPackage(uid, finalIntent,
- resolvedType, key.packageName, userId);
+ owner.startServiceInPackage(uid, finalIntent, resolvedType,
+ key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
+ key.packageName, userId);
} catch (RuntimeException e) {
Slog.w(TAG, "Unable to send startService intent", e);
} catch (TransactionTooLargeException e) {
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dfbe59f1c8f2..44ebf50eb31a 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -92,6 +92,8 @@ final class ServiceRecord extends Binder {
ServiceState restartTracker; // tracking service restart
boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
boolean delayed; // are we waiting to start this service in the background?
+ boolean fgRequired; // is the service required to go foreground after starting?
+ boolean fgWaiting; // is a timeout for going foreground already scheduled?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
Notification foregroundNoti; // Notification record of foreground state.
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index fd65c101919d..ce32f8413468 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -112,6 +112,7 @@ import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static java.lang.Integer.MAX_VALUE;
@@ -617,15 +618,15 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
boolean kept = true;
try {
final ActivityRecord r = topRunningActivityLocked();
- final boolean wasFocused = supervisor.isFocusedStack(sourceStack)
+ final boolean wasFocused = r != null && supervisor.isFocusedStack(sourceStack)
&& (topRunningActivityLocked() == r);
- final boolean wasResumed = sourceStack.mResumedActivity == r;
- final boolean wasPaused = sourceStack.mPausingActivity == r;
+ final boolean wasResumed = r != null && sourceStack.mResumedActivity == r;
+ final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
// In some cases the focused stack isn't the front stack. E.g. pinned stack.
// Whenever we are moving the top activity from the front stack we want to make sure to
// move the stack to the front.
- final boolean wasFront = supervisor.isFrontStackOnDisplay(sourceStack)
+ final boolean wasFront = r != null && supervisor.isFrontStackOnDisplay(sourceStack)
&& (sourceStack.topRunningActivityLocked() == r);
// Adjust the position for the new parent stack as needed.
@@ -667,8 +668,10 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
// new stack by moving the stack to the front.
final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
|| (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
- toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed, wasPaused,
- reason);
+ if (r != null) {
+ toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
+ wasPaused, reason);
+ }
if (!animate) {
toStack.mNoAnimActivities.add(topActivity);
}
@@ -1278,6 +1281,26 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
return false;
}
+ /**
+ * @return whether or not there are ONLY task overlay activities in the stack.
+ * If {@param excludeFinishing} is set, then ignore finishing activities in the check.
+ * If there are no task overlay activities, this call returns false.
+ */
+ boolean onlyHasTaskOverlayActivities(boolean excludeFinishing) {
+ int count = 0;
+ for (int i = mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mActivities.get(i);
+ if (excludeFinishing && r.finishing) {
+ continue;
+ }
+ if (!r.mTaskOverlay) {
+ return false;
+ }
+ count++;
+ }
+ return count > 0;
+ }
+
boolean autoRemoveFromRecents() {
// We will automatically remove the task either if it has explicitly asked for
// this, or it is empty and has never contained an activity that got shown to
@@ -1289,7 +1312,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
* Completely remove all activities associated with an existing
* task starting at a specified index.
*/
- final void performClearTaskAtIndexLocked(int activityNdx) {
+ final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately) {
int numActivities = mActivities.size();
for ( ; activityNdx < numActivities; ++activityNdx) {
final ActivityRecord r = mActivities.get(activityNdx);
@@ -1302,8 +1325,8 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
mActivities.remove(activityNdx);
--activityNdx;
--numActivities;
- } else if (mStack.finishActivityLocked(
- r, Activity.RESULT_CANCELED, null, "clear-task-index", false)) {
+ } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
+ "clear-task-index", false, pauseImmediately)) {
--activityNdx;
--numActivities;
}
@@ -1315,7 +1338,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
*/
final void performClearTaskLocked() {
mReuseTask = true;
- performClearTaskAtIndexLocked(0);
+ performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY);
mReuseTask = false;
}
@@ -1399,9 +1422,9 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
return taskThumbnail;
}
- void removeTaskActivitiesLocked() {
+ void removeTaskActivitiesLocked(boolean pauseImmediately) {
// Just remove the entire task.
- performClearTaskAtIndexLocked(0);
+ performClearTaskAtIndexLocked(0, pauseImmediately);
}
String lockTaskAuthToString() {
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index 6710bdc3cd2d..9970c82e2c75 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -88,7 +88,7 @@ public final class UserState {
state = newState;
}
- static String stateToString(int state) {
+ public static String stateToString(int state) {
switch (state) {
case STATE_BOOTING: return "BOOTING";
case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 333d27bd5360..49d1521e378f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -106,6 +106,7 @@ import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IntArray;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
@@ -126,6 +127,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -575,6 +577,10 @@ public class AudioService extends IAudioService.Stub
private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
private long mLoweredFromNormalToVibrateTime;
+ // Array of Uids of valid accessibility services to check if caller is one of them
+ private int[] mAccessibilityServiceUids;
+ private final Object mAccessibilityServiceUidsLock = new Object();
+
// Intent "extra" data keys.
public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName";
public static final String CONNECT_INTENT_KEY_STATE = "state";
@@ -1241,11 +1247,9 @@ public class AudioService extends IAudioService.Stub
/** @see AudioManager#adjustStreamVolume(int, int, int) */
public void adjustStreamVolume(int streamType, int direction, int flags,
String callingPackage) {
- if ( streamType == AudioManager.STREAM_ACCESSIBILITY
- && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) {
+ if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
- + "BIND_ACCESSIBILITY_SERVICE / callingPackage=" + callingPackage);
+ + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
return;
}
adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
@@ -1559,17 +1563,33 @@ public class AudioService extends IAudioService.Stub
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
- if ( streamType == AudioManager.STREAM_ACCESSIBILITY
- && (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE))) {
+ if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
- + " BIND_ACCESSIBILITY_SERVICE callingPackage=" + callingPackage);
+ + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage);
return;
}
setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
Binder.getCallingUid());
}
+ private boolean canChangeAccessibilityVolume() {
+ synchronized (mAccessibilityServiceUidsLock) {
+ if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
+ return true;
+ }
+ if (mAccessibilityServiceUids != null) {
+ int callingUid = Binder.getCallingUid();
+ for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
+ if (mAccessibilityServiceUids[i] == callingUid) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
String caller, int uid) {
if (DEBUG_VOL) {
@@ -6380,6 +6400,29 @@ public class AudioService extends IAudioService.Stub
}
}
}
+
+ @Override
+ public void setAccessibilityServiceUids(IntArray uids) {
+ synchronized (mAccessibilityServiceUidsLock) {
+ if (uids.size() == 0) {
+ mAccessibilityServiceUids = null;
+ } else {
+ boolean changed = (mAccessibilityServiceUids == null)
+ || (mAccessibilityServiceUids.length != uids.size());
+ if (!changed) {
+ for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
+ if (uids.get(i) != mAccessibilityServiceUids[i]) {
+ changed = true;
+ break;
+ }
+ }
+ }
+ if (changed) {
+ mAccessibilityServiceUids = uids.toArray();
+ }
+ }
+ }
+ }
}
//==========================================================================================
@@ -6555,7 +6598,7 @@ public class AudioService extends IAudioService.Stub
public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
final boolean isPrivileged =
- (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+ (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_AUDIO_ROUTING));
mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
}
@@ -6566,7 +6609,7 @@ public class AudioService extends IAudioService.Stub
public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
final boolean isPrivileged =
- (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+ (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_AUDIO_ROUTING));
return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
}
diff --git a/services/core/java/com/android/server/connectivity/MockableSystemProperties.java b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
index 4f68652d412c..77b86d8e4355 100644
--- a/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
+++ b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
@@ -19,7 +19,20 @@ package com.android.server.connectivity;
import android.os.SystemProperties;
public class MockableSystemProperties {
+
+ public String get(String key) {
+ return SystemProperties.get(key);
+ }
+
+ public int getInt(String key, int def) {
+ return SystemProperties.getInt(key, def);
+ }
+
public boolean getBoolean(String key, boolean def) {
return SystemProperties.getBoolean(key, def);
}
+
+ public void set(String key, String value) {
+ SystemProperties.set(key, value);
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 9fc2fc7bb31e..248f96994314 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -32,7 +32,6 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -139,6 +138,7 @@ public class Vpn {
private NetworkAgent mNetworkAgent;
private final Looper mLooper;
private final NetworkCapabilities mNetworkCapabilities;
+ private final SystemServices mSystemServices;
/**
* Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
@@ -206,7 +206,7 @@ public class Vpn {
final boolean isPackageRemoved = !intent.getBooleanExtra(
Intent.EXTRA_REPLACING, false);
if (isPackageRemoved) {
- setAndSaveAlwaysOnPackage(null, false);
+ setAlwaysOnPackage(null, false);
}
break;
}
@@ -217,11 +217,18 @@ public class Vpn {
private boolean mIsPackageIntentReceiverRegistered = false;
public Vpn(Looper looper, Context context, INetworkManagementService netService,
- int userHandle) {
+ @UserIdInt int userHandle) {
+ this(looper, context, netService, userHandle, new SystemServices(context));
+ }
+
+ @VisibleForTesting
+ protected Vpn(Looper looper, Context context, INetworkManagementService netService,
+ int userHandle, SystemServices systemServices) {
mContext = context;
mNetd = netService;
mUserHandle = userHandle;
mLooper = looper;
+ mSystemServices = systemServices;
mPackage = VpnConfig.LEGACY_VPN;
mOwnerUID = getAppUid(mPackage, mUserHandle);
@@ -237,6 +244,8 @@ public class Vpn {
mNetworkCapabilities = new NetworkCapabilities();
mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
+
+ loadAlwaysOnPackage();
}
/**
@@ -275,6 +284,26 @@ public class Vpn {
*/
public synchronized boolean setAlwaysOnPackage(String packageName, boolean lockdown) {
enforceControlPermissionOrInternalCaller();
+
+ if (setAlwaysOnPackageInternal(packageName, lockdown)) {
+ saveAlwaysOnPackage();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Configures an always-on VPN connection through a specific application, the same as
+ * {@link #setAlwaysOnPackage}.
+ *
+ * Does not perform permission checks. Does not persist any of the changes to storage.
+ *
+ * @param packageName the package to designate as always-on VPN supplier.
+ * @param lockdown whether to prevent traffic outside of a VPN, for example while connecting.
+ * @return {@code true} if the package has been set as always-on, {@code false} otherwise.
+ */
+ @GuardedBy("this")
+ private boolean setAlwaysOnPackageInternal(String packageName, boolean lockdown) {
if (VpnConfig.LEGACY_VPN.equals(packageName)) {
Log.w(TAG, "Not setting legacy VPN \"" + packageName + "\" as always-on.");
return false;
@@ -347,13 +376,13 @@ public class Vpn {
/**
* Save the always-on package and lockdown config into Settings.Secure
*/
- public synchronized void saveAlwaysOnPackage() {
+ @GuardedBy("this")
+ private void saveAlwaysOnPackage() {
final long token = Binder.clearCallingIdentity();
try {
- final ContentResolver cr = mContext.getContentResolver();
- Settings.Secure.putStringForUser(cr, Settings.Secure.ALWAYS_ON_VPN_APP,
+ mSystemServices.settingsSecurePutStringForUser(Settings.Secure.ALWAYS_ON_VPN_APP,
getAlwaysOnPackage(), mUserHandle);
- Settings.Secure.putIntForUser(cr, Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN,
+ mSystemServices.settingsSecurePutIntForUser(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN,
(mLockdown ? 1 : 0), mUserHandle);
} finally {
Binder.restoreCallingIdentity(token);
@@ -361,18 +390,19 @@ public class Vpn {
}
/**
- * Set and save always-on package and lockdown config
- * @see Vpn#setAlwaysOnPackage(String, boolean)
- * @see Vpn#saveAlwaysOnPackage()
- *
- * @return result of Vpn#setAndSaveAlwaysOnPackage(String, boolean)
+ * Load the always-on package and lockdown config from Settings.Secure
*/
- private synchronized boolean setAndSaveAlwaysOnPackage(String packageName, boolean lockdown) {
- if (setAlwaysOnPackage(packageName, lockdown)) {
- saveAlwaysOnPackage();
- return true;
- } else {
- return false;
+ @GuardedBy("this")
+ private void loadAlwaysOnPackage() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final String alwaysOnPackage = mSystemServices.settingsSecureGetStringForUser(
+ Settings.Secure.ALWAYS_ON_VPN_APP, mUserHandle);
+ final boolean alwaysOnLockdown = mSystemServices.settingsSecureGetIntForUser(
+ Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, 0 /*default*/, mUserHandle) != 0;
+ setAlwaysOnPackageInternal(alwaysOnPackage, alwaysOnLockdown);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -1276,11 +1306,7 @@ public class Vpn {
private void updateAlwaysOnNotification(DetailedState networkState) {
final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);
- updateAlwaysOnNotificationInternal(visible);
- }
- @VisibleForTesting
- protected void updateAlwaysOnNotificationInternal(boolean visible) {
final UserHandle user = UserHandle.of(mUserHandle);
final long token = Binder.clearCallingIdentity();
try {
@@ -1290,10 +1316,8 @@ public class Vpn {
return;
}
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
- final PendingIntent configIntent = PendingIntent.getActivityAsUser(
- mContext, /* request */ 0, intent,
- PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
- null, user);
+ final PendingIntent configIntent = mSystemServices.pendingIntentGetActivityAsUser(
+ intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, user);
final Notification.Builder builder =
new Notification.Builder(mContext, SystemNotificationChannels.VPN)
.setSmallIcon(R.drawable.vpn_connected)
@@ -1310,6 +1334,58 @@ public class Vpn {
}
}
+ /**
+ * Facade for system service calls that change, or depend on, state outside of
+ * {@link ConnectivityService} and have hard-to-mock interfaces.
+ *
+ * @see com.android.server.connectivity.VpnTest
+ */
+ @VisibleForTesting
+ public static class SystemServices {
+ private final Context mContext;
+
+ public SystemServices(@NonNull Context context) {
+ mContext = context;
+ }
+
+ /**
+ * @see PendingIntent#getActivityAsUser()
+ */
+ public PendingIntent pendingIntentGetActivityAsUser(
+ Intent intent, int flags, UserHandle user) {
+ return PendingIntent.getActivityAsUser(mContext, 0 /*request*/, intent, flags,
+ null /*options*/, user);
+ }
+
+ /**
+ * @see Settings.Secure#putStringForUser
+ */
+ public void settingsSecurePutStringForUser(String key, String value, int userId) {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(), key, value, userId);
+ }
+
+ /**
+ * @see Settings.Secure#putIntForUser
+ */
+ public void settingsSecurePutIntForUser(String key, int value, int userId) {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(), key, value, userId);
+ }
+
+ /**
+ * @see Settings.Secure#getStringForUser
+ */
+ public String settingsSecureGetStringForUser(String key, int userId) {
+ return Settings.Secure.getStringForUser(mContext.getContentResolver(), key, userId);
+ }
+
+ /**
+ * @see Settings.Secure#getIntForUser
+ */
+ public int settingsSecureGetIntForUser(String key, int def, int userId) {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(), key, def, userId);
+ }
+ }
+
private native int jniCreate(int mtu);
private native String jniGetName(int tun);
private native int jniSetAddresses(String interfaze, String addresses);
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index bbad493a913f..1a27a39bd1bf 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -907,7 +907,12 @@ public class SyncManager {
Bundle finalExtras = new Bundle(extras);
String packageName = syncAdapterInfo.componentName.getPackageName();
// If the app did not run and has no account access, done
- if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) {
+ try {
+ if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) {
+ continue;
+ }
+ } catch (IllegalArgumentException e) {
+ // Package not found, race with an uninstall
continue;
}
mAccountManagerInternal.requestAccountAccess(account.account,
diff --git a/services/core/java/com/android/server/fingerprint/EnumerateClient.java b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
index 1b8b89c8bc37..34f245f19d12 100644
--- a/services/core/java/com/android/server/fingerprint/EnumerateClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
@@ -58,7 +58,7 @@ public abstract class EnumerateClient extends ClientMonitor {
public int stop(boolean initiatedByClient) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
- Slog.w(TAG, "stopEnumeration: no fingerprint HAL!");
+ Slog.w(TAG, "stopAuthentication: no fingerprint HAL!");
return ERROR_ESRCH;
}
try {
@@ -102,12 +102,12 @@ public abstract class EnumerateClient extends ClientMonitor {
@Override
public boolean onEnrollResult(int fingerId, int groupId, int rem) {
if (DEBUG) Slog.w(TAG, "onEnrollResult() called for enumerate!");
- return true; // Invalid for Enumerate.
+ return true; // Invalid for Remove
}
@Override
public boolean onRemoved(int fingerId, int groupId, int remaining) {
if (DEBUG) Slog.w(TAG, "onRemoved() called for enumerate!");
- return true; // Invalid for Enumerate.
+ return true; // Invalid for Authenticate
}
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index b6e7932bdec4..7d97ce41e8f3 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -85,7 +85,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.LinkedList;
/**
* A service to manage multiple clients that want to access the fingerprint HAL API.
@@ -135,20 +134,6 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
private ClientMonitor mPendingClient;
private PerformanceStats mPerformanceStats;
-
- private IBinder mToken = new Binder(); // used for internal FingerprintService enumeration
- private LinkedList<Integer> mEnumeratingUserIds = new LinkedList<>();
- private ArrayList<UserFingerprint> mUnknownFingerprints = new ArrayList<>(); // hw finterprints
-
- private class UserFingerprint {
- Fingerprint f;
- int userId;
- public UserFingerprint(Fingerprint f, int userId) {
- this.f = f;
- this.userId = userId;
- }
- }
-
// Normal fingerprint authentications are tracked by mPerformanceMap.
private HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>();
@@ -272,12 +257,10 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
// This operation can be expensive, so keep track of the elapsed time. Might need to move to
// background if it takes too long.
long t = System.currentTimeMillis();
+
mAuthenticatorIds.clear();
- mEnumeratingUserIds.clear();
- mUnknownFingerprints.clear();
for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) {
int userId = getUserOrWorkProfileId(null, user.id);
- mEnumeratingUserIds.add(userId);
if (!mAuthenticatorIds.containsKey(userId)) {
updateActiveGroup(userId, null);
}
@@ -287,70 +270,12 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
if (t > 1000) {
Slog.w(TAG, "loadAuthenticatorIds() taking too long: " + t + "ms");
}
-
- if (!mEnumeratingUserIds.isEmpty()) {
- enumerateNextUser();
- }
- }
-
- private void enumerateNextUser() {
- int nextUser = mEnumeratingUserIds.getFirst();
- updateActiveGroup(nextUser, null);
- boolean restricted = !hasPermission(MANAGE_FINGERPRINT);
-
- if (DEBUG) Slog.v(TAG, "Enumerating user id " + nextUser + " of "
- + mEnumeratingUserIds.size() + " remaining users");
-
- startEnumerate(mToken, nextUser, null, restricted, true /* internal */);
- }
-
- // Remove unknown fingerprints from hardware
- private void cleanupUnknownFingerprints() {
- if (!mUnknownFingerprints.isEmpty()) {
- Slog.w(TAG, "unknown fingerprint size: " + mUnknownFingerprints.size());
- UserFingerprint uf = mUnknownFingerprints.get(0);
- mUnknownFingerprints.remove(uf);
- boolean restricted = !hasPermission(MANAGE_FINGERPRINT);
- updateActiveGroup(uf.userId, null);
- startRemove(mToken, uf.f.getFingerId(), uf.f.getGroupId(), uf.userId, null,
- restricted, true /* internal */);
- }
}
protected void handleEnumerate(long deviceId, int fingerId, int groupId, int remaining) {
- if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId
- + ", gid=" + groupId
- + ", dev=" + deviceId
- + ", rem=" + remaining);
-
- ClientMonitor client = mCurrentClient;
-
- if (client != null) {
- client.onEnumerationResult(fingerId, groupId, remaining);
- }
-
- // All fingerprints in hardware for this user were enumerated
- if (remaining == 0) {
- mEnumeratingUserIds.poll();
-
- if (client instanceof InternalEnumerateClient) {
- List<Fingerprint> enrolled = ((InternalEnumerateClient) client).getEnumeratedList();
- Slog.w(TAG, "Added " + enrolled.size() + " enumerated fingerprints for deletion");
- for (Fingerprint f : enrolled) {
- mUnknownFingerprints.add(new UserFingerprint(f, client.getTargetUserId()));
- }
- }
-
- removeClient(client);
-
- if (!mEnumeratingUserIds.isEmpty()) {
- enumerateNextUser();
- } else if (client instanceof InternalEnumerateClient) {
- if (DEBUG) Slog.v(TAG, "Finished enumerating all users");
- // This will start a chain of InternalRemovalClients
- cleanupUnknownFingerprints();
- }
- }
+ if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId + ", gid="
+ + groupId + "rem=" + remaining);
+ // TODO: coordinate names with framework
}
protected void handleError(long deviceId, int error, int vendorCode) {
@@ -379,18 +304,10 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
}
protected void handleRemoved(long deviceId, int fingerId, int groupId, int remaining) {
- if (DEBUG) Slog.w(TAG, "Removed: fid=" + fingerId
- + ", gid=" + groupId
- + ", dev=" + deviceId
- + ", rem=" + remaining);
-
ClientMonitor client = mCurrentClient;
if (client != null && client.onRemoved(fingerId, groupId, remaining)) {
removeClient(client);
}
- if (client instanceof InternalRemovalClient && !mUnknownFingerprints.isEmpty()) {
- cleanupUnknownFingerprints();
- }
}
protected void handleAuthenticated(long deviceId, int fingerId, int groupId,
@@ -517,15 +434,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
ClientMonitor currentClient = mCurrentClient;
if (currentClient != null) {
if (DEBUG) Slog.v(TAG, "request stop current client " + currentClient.getOwnerString());
- if (currentClient instanceof InternalEnumerateClient ||
- currentClient instanceof InternalRemovalClient) {
- // This condition means we're currently running internal diagnostics to
- // remove extra fingerprints in the hardware and/or the software
- // TODO: design an escape hatch in case client never finishes
- }
- else {
- currentClient.stop(initiatedByClient);
- }
+ currentClient.stop(initiatedByClient);
mPendingClient = newClient;
mHandler.removeCallbacks(mResetClientState);
mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
@@ -542,86 +451,47 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
}
void startRemove(IBinder token, int fingerId, int groupId, int userId,
- IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) {
+ IFingerprintServiceReceiver receiver, boolean restricted) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "startRemove: no fingerprint HAL!");
return;
}
+ RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token,
+ receiver, fingerId, groupId, userId, restricted, token.toString()) {
+ @Override
+ public void notifyUserActivity() {
+ FingerprintService.this.userActivity();
+ }
- if (internal) {
- Context context = getContext();
- InternalRemovalClient client = new InternalRemovalClient(context, mHalDeviceId,
- token, receiver, fingerId, groupId, userId, restricted,
- context.getOpPackageName()) {
- @Override
- public void notifyUserActivity() {
-
- }
- @Override
- public IBiometricsFingerprint getFingerprintDaemon() {
- return FingerprintService.this.getFingerprintDaemon();
- }
- };
- startClient(client, true);
- }
- else {
- RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token,
- receiver, fingerId, groupId, userId, restricted, token.toString()) {
- @Override
- public void notifyUserActivity() {
- FingerprintService.this.userActivity();
- }
-
- @Override
- public IBiometricsFingerprint getFingerprintDaemon() {
- return FingerprintService.this.getFingerprintDaemon();
- }
- };
- startClient(client, true);
- }
+ @Override
+ public IBiometricsFingerprint getFingerprintDaemon() {
+ return FingerprintService.this.getFingerprintDaemon();
+ }
+ };
+ startClient(client, true);
}
void startEnumerate(IBinder token, int userId,
- IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) {
+ IFingerprintServiceReceiver receiver, boolean restricted) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "startEnumerate: no fingerprint HAL!");
return;
}
- if (internal) {
- List<Fingerprint> enrolledList = getEnrolledFingerprints(userId);
- Context context = getContext();
- InternalEnumerateClient client = new InternalEnumerateClient(context, mHalDeviceId,
- token, receiver, userId, userId, restricted, context.getOpPackageName(),
- enrolledList) {
- @Override
- public void notifyUserActivity() {
-
- }
-
- @Override
- public IBiometricsFingerprint getFingerprintDaemon() {
- return FingerprintService.this.getFingerprintDaemon();
- }
- };
- startClient(client, true);
- }
- else {
- EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token,
- receiver, userId, userId, restricted, token.toString()) {
- @Override
- public void notifyUserActivity() {
- FingerprintService.this.userActivity();
- }
+ EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token,
+ receiver, userId, userId, restricted, token.toString()) {
+ @Override
+ public void notifyUserActivity() {
+ FingerprintService.this.userActivity();
+ }
- @Override
- public IBiometricsFingerprint getFingerprintDaemon() {
- return FingerprintService.this.getFingerprintDaemon();
- }
- };
- startClient(client, true);
- }
+ @Override
+ public IBiometricsFingerprint getFingerprintDaemon() {
+ return FingerprintService.this.getFingerprintDaemon();
+ }
+ };
+ startClient(client, true);
}
public List<Fingerprint> getEnrolledFingerprints(int userId) {
@@ -1108,14 +978,12 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
mHandler.post(new Runnable() {
@Override
public void run() {
- startRemove(token, fingerId, groupId, userId, receiver,
- restricted, false /* internal */);
+ startRemove(token, fingerId, groupId, userId, receiver, restricted);
}
});
}
- @Override // Binder call
public void enumerate(final IBinder token, final int userId,
final IFingerprintServiceReceiver receiver) {
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
@@ -1123,7 +991,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
mHandler.post(new Runnable() {
@Override
public void run() {
- startEnumerate(token, userId, receiver, restricted, false /* internal */);
+ startEnumerate(token, userId, receiver, restricted);
}
});
diff --git a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java b/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
deleted file mode 100644
index f4d2596c85bf..000000000000
--- a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.fingerprint;
-
-import android.content.Context;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.os.IBinder;
-import android.util.Slog;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An internal class to help clean up unknown fingerprints in the hardware and software
- */
-public abstract class InternalEnumerateClient extends EnumerateClient {
-
- private List<Fingerprint> mEnrolledList;
- private List<Fingerprint> mEnumeratedList = new ArrayList<>(); // list of fp to delete
-
- public InternalEnumerateClient(Context context, long halDeviceId, IBinder token,
- IFingerprintServiceReceiver receiver, int groupId, int userId,
- boolean restricted, String owner, List<Fingerprint> enrolledList) {
-
- super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner);
- mEnrolledList = enrolledList;
- }
-
- private void handleEnumeratedFingerprint(int fingerId, int groupId, int remaining) {
-
- boolean matched = false;
- for (int i=0; i<mEnrolledList.size(); i++) {
- if (mEnrolledList.get(i).getFingerId() == fingerId) {
- mEnrolledList.remove(i);
- matched = true;
- Slog.e(TAG, "Matched fingerprint fid=" + fingerId);
- break;
- }
- }
-
- // fingerId 0 means no fingerprints are in hardware
- if (!matched && fingerId != 0) {
- Fingerprint fingerprint = new Fingerprint("", groupId, fingerId, getHalDeviceId());
- mEnumeratedList.add(fingerprint);
- }
- }
-
- private void doFingerprintCleanup() {
-
- if (mEnrolledList == null) {
- return;
- }
-
- for (Fingerprint f : mEnrolledList) {
- Slog.e(TAG, "Internal Enumerate: Removing dangling enrolled fingerprint: "
- + f.getName() + " " + f.getFingerId() + " " + f.getGroupId()
- + " " + f.getDeviceId());
-
- FingerprintUtils.getInstance().removeFingerprintIdForUser(getContext(),
- f.getFingerId(), getTargetUserId());
- }
- mEnrolledList.clear();
- }
-
- public List<Fingerprint> getEnumeratedList() {
- return mEnumeratedList;
- }
-
- @Override
- public boolean onEnumerationResult(int fingerId, int groupId, int remaining) {
-
- handleEnumeratedFingerprint(fingerId, groupId, remaining);
- if (remaining == 0) {
- doFingerprintCleanup();
- }
-
- return fingerId == 0; // done when id hits 0
- }
-
-}
diff --git a/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java b/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java
deleted file mode 100644
index 19f61feac1f4..000000000000
--- a/services/core/java/com/android/server/fingerprint/InternalRemovalClient.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.fingerprint;
-
-import android.content.Context;
-import android.os.IBinder;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import com.android.server.fingerprint.RemovalClient;
-
-public abstract class InternalRemovalClient extends RemovalClient {
-
- public InternalRemovalClient(Context context, long halDeviceId, IBinder token,
- IFingerprintServiceReceiver receiver, int fingerId, int groupId, int userId,
- boolean restricted, String owner) {
-
- super(context, halDeviceId, token, receiver, fingerId, groupId, userId, restricted, owner);
-
- }
-}
diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
new file mode 100644
index 000000000000..c6dc11c53393
--- /dev/null
+++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.Context;
+import android.media.AudioManager.AudioPlaybackCallback;
+import android.media.AudioPlaybackConfiguration;
+import android.media.IAudioService;
+import android.media.IPlaybackConfigDispatcher;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.IntArray;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Monitors changes in audio playback and notify the newly started audio playback through the
+ * {@link OnAudioPlaybackStartedListener}.
+ */
+class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub {
+ private static boolean DEBUG = MediaSessionService.DEBUG;
+ private static String TAG = "AudioPlaybackMonitor";
+
+ /**
+ * Called when audio playback is started for a given UID.
+ */
+ interface OnAudioPlaybackStartedListener {
+ void onAudioPlaybackStarted(int uid);
+ }
+
+ private final Object mLock = new Object();
+ private final Context mContext;
+ private final OnAudioPlaybackStartedListener mListener;
+
+ private Set<Integer> mActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
+ private Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
+
+ // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video)
+ // The UID whose audio playback becomes active at the last comes first.
+ // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
+ private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
+
+ AudioPlaybackMonitor(Context context, IAudioService audioService,
+ OnAudioPlaybackStartedListener listener) {
+ mContext = context;
+ mListener = listener;
+ try {
+ audioService.registerPlaybackCallback(this);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Failed to register playback callback", e);
+ }
+ }
+
+ /**
+ * Called when the {@link AudioPlaybackConfiguration} is updated.
+ * <p>If an app starts audio playback, the app's local media session will be the media button
+ * session. If the app has multiple media sessions, the playback active local session will be
+ * picked.
+ *
+ * @param configs List of the current audio playback configuration
+ */
+ @Override
+ public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ Set<Integer> newActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
+ List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>();
+ synchronized (mLock) {
+ mActiveAudioPlaybackClientUids.clear();
+ for (AudioPlaybackConfiguration config : configs) {
+ // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL
+ // (i.e. playback from the SoundPool class which is only for sound effects)
+ // playback.
+ // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM
+ // specific audio/video players.
+ if (!config.isActive()
+ || config.getPlayerType()
+ == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
+ continue;
+ }
+ mActiveAudioPlaybackClientUids.add(config.getClientUid());
+
+ newActiveAudioPlaybackPlayerInterfaceIds.add(config.getPlayerInterfaceId());
+ if (!mActiveAudioPlaybackPlayerInterfaceIds.contains(
+ config.getPlayerInterfaceId())) {
+ if (DEBUG) {
+ Log.d(TAG, "Found a new active media playback. " +
+ AudioPlaybackConfiguration.toLogFriendlyString(config));
+ }
+ // New active audio playback.
+ newActiveAudioPlaybackClientUids.add(config.getClientUid());
+ int index = mSortedAudioPlaybackClientUids.indexOf(config.getClientUid());
+ if (index == 0) {
+ // It's the lastly played music app already. Skip updating.
+ continue;
+ } else if (index > 0) {
+ mSortedAudioPlaybackClientUids.remove(index);
+ }
+ mSortedAudioPlaybackClientUids.add(0, config.getClientUid());
+ }
+ }
+ mActiveAudioPlaybackPlayerInterfaceIds.clear();
+ mActiveAudioPlaybackPlayerInterfaceIds = newActiveAudioPlaybackPlayerInterfaceIds;
+ }
+ for (int uid : newActiveAudioPlaybackClientUids) {
+ mListener.onAudioPlaybackStarted(uid);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ /**
+ * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
+ * audio/video) The UID whose audio playback becomes active at the last comes first.
+ */
+ public IntArray getSortedAudioPlaybackClientUids() {
+ IntArray sortedAudioPlaybackClientUids = new IntArray();
+ synchronized (mLock) {
+ sortedAudioPlaybackClientUids.addAll(mSortedAudioPlaybackClientUids);
+ }
+ return sortedAudioPlaybackClientUids;
+ }
+
+ /**
+ * Returns if the audio playback is active for the uid.
+ */
+ public boolean isPlaybackActive(int uid) {
+ synchronized (mLock) {
+ return mActiveAudioPlaybackClientUids.contains(uid);
+ }
+ }
+
+ /**
+ * Cleans up the sorted list of audio playback client UIDs with given {@param
+ * mediaButtonSessionUid}.
+ * <p>UIDs whose audio playback started after the media button session's audio playback
+ * cannot be the lastly played media app. So they won't needed anymore.
+ *
+ * @param mediaButtonSessionUid UID of the media button session.
+ */
+ public void cleanUpAudioPlaybackUids(int mediaButtonSessionUid) {
+ synchronized (mLock) {
+ int userId = UserHandle.getUserId(mediaButtonSessionUid);
+ for (int i = mSortedAudioPlaybackClientUids.size() - 1; i >= 0; i--) {
+ if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) {
+ break;
+ }
+ if (userId == UserHandle.getUserId(mSortedAudioPlaybackClientUids.get(i))) {
+ // Clean up unnecessary UIDs.
+ // It doesn't need to be managed profile aware because it's just to prevent
+ // the list from increasing indefinitely. The media button session updating
+ // shouldn't be affected by cleaning up.
+ mSortedAudioPlaybackClientUids.remove(i);
+ }
+ }
+ }
+ }
+
+ /**
+ * Dumps {@link AudioPlaybackMonitor}.
+ */
+ public void dump(PrintWriter pw, String prefix) {
+ synchronized (mLock) {
+ pw.println(prefix + "Audio playback (lastly played comes first)");
+ String indent = prefix + " ";
+ for (int i = 0; i < mSortedAudioPlaybackClientUids.size(); i++) {
+ int uid = mSortedAudioPlaybackClientUids.get(i);
+ pw.print(indent + "uid=" + uid + " packages=");
+ String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
+ if (packages != null && packages.length > 0) {
+ for (int j = 0; j < packages.length; j++) {
+ pw.print(packages[j] + " ");
+ }
+ }
+ pw.println();
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 20663a09699d..53a8092fa558 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -66,12 +66,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
- * The length of time a session will still be considered active after
- * pausing in ms.
- */
- private static final int ACTIVE_BUFFER = 30000;
-
- /**
* The amount of time we'll send an assumed volume after the last volume
* command before reverting to the last reported volume.
*/
@@ -109,7 +103,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private int mRatingType;
private int mRepeatMode;
private boolean mShuffleModeEnabled;
- private long mLastActiveTime;
// End TransportPerformer fields
// Volume handling fields
@@ -130,7 +123,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private String mCallingPackage;
public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName,
- ISessionCallback cb, String tag, MediaSessionService service, Handler handler) {
+ ISessionCallback cb, String tag, MediaSessionService service, Looper handlerLooper) {
mOwnerPid = ownerPid;
mOwnerUid = ownerUid;
mUserId = userId;
@@ -140,7 +133,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
mSession = new SessionStub();
mSessionCb = new SessionCb(cb);
mService = service;
- mHandler = new MessageHandler(handler.getLooper());
+ mHandler = new MessageHandler(handlerLooper);
mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
@@ -211,6 +204,15 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
/**
+ * Get the UID this session was created for.
+ *
+ * @return The UID for this session.
+ */
+ public int getUid() {
+ return mOwnerUid;
+ }
+
+ /**
* Get the user id this session was created for.
*
* @return The user id for this session.
@@ -244,7 +246,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
public void adjustVolume(int direction, int flags, String packageName, int uid,
boolean useSuggested) {
int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
- if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
+ if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
@@ -320,25 +322,13 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
/**
- * Check if the session is currently performing playback. This will also
- * return true if the session was recently paused.
+ * Check if the session is currently performing playback.
*
- * @param includeRecentlyActive True if playback that was recently paused
- * should count, false if it shouldn't.
* @return True if the session is performing playback, false otherwise.
*/
- public boolean isPlaybackActive(boolean includeRecentlyActive) {
- int state = mPlaybackState == null ? 0 : mPlaybackState.getState();
- if (MediaSession.isActiveState(state)) {
- return true;
- }
- if (includeRecentlyActive && state == mPlaybackState.STATE_PAUSED) {
- long inactiveTime = SystemClock.uptimeMillis() - mLastActiveTime;
- if (inactiveTime < ACTIVE_BUFFER) {
- return true;
- }
- }
- return false;
+ public boolean isPlaybackActive() {
+ int state = mPlaybackState == null ? PlaybackState.STATE_NONE : mPlaybackState.getState();
+ return MediaSession.isActiveState(state);
}
/**
@@ -456,7 +446,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
@Override
public String toString() {
- return mPackageName + "/" + mTag + " (uid=" + mUserId + ")";
+ return mPackageName + "/" + mTag + " (userId=" + mUserId + ")";
}
private void postAdjustLocalVolume(final int stream, final int direction, final int flags,
@@ -782,7 +772,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private final class SessionStub extends ISession.Stub {
@Override
public void destroy() {
- mService.destroySession(MediaSessionRecord.this);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mService.destroySession(MediaSessionRecord.this);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
@@ -817,6 +812,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
@Override
public void setMediaButtonReceiver(PendingIntent pi) {
mMediaButtonReceiver = pi;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
@@ -842,15 +843,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
@Override
public void setPlaybackState(PlaybackState state) {
- int oldState = mPlaybackState == null ? 0 : mPlaybackState.getState();
- int newState = state == null ? 0 : state.getState();
- if (MediaSession.isActiveState(oldState) && newState == PlaybackState.STATE_PAUSED) {
- mLastActiveTime = SystemClock.elapsedRealtime();
- }
+ int oldState = mPlaybackState == null
+ ? PlaybackState.STATE_NONE : mPlaybackState.getState();
+ int newState = state == null
+ ? PlaybackState.STATE_NONE : state.getState();
synchronized (mLock) {
mPlaybackState = state;
}
- mService.onSessionPlaystateChange(MediaSessionRecord.this, oldState, newState);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mService.onSessionPlaystateChanged(MediaSessionRecord.this, oldState, newState);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE);
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index ea9128fd6e2f..4bf9d8f5ff53 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -57,11 +57,13 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.speech.RecognizerIntent;
import android.text.TextUtils;
+import android.util.IntArray;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -85,7 +87,7 @@ import java.util.List;
*/
public class MediaSessionService extends SystemService implements Monitor {
private static final String TAG = "MediaSessionService";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
// Leave log for key event always.
private static final boolean DEBUG_KEY_EVENT = true;
@@ -114,6 +116,7 @@ public class MediaSessionService extends SystemService implements Monitor {
// It's always not null after the MediaSessionService is started.
private FullUserRecord mCurrentFullUserRecord;
private MediaSessionRecord mGlobalPrioritySession;
+ private AudioPlaybackMonitor mAudioPlaybackMonitor;
// Used to notify system UI when remote volume was changed. TODO find a
// better way to handle this.
@@ -134,6 +137,19 @@ public class MediaSessionService extends SystemService implements Monitor {
mKeyguardManager =
(KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
mAudioService = getAudioService();
+ mAudioPlaybackMonitor = new AudioPlaybackMonitor(getContext(), mAudioService,
+ new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() {
+ @Override
+ public void onAudioPlaybackStarted(int uid) {
+ synchronized (mLock) {
+ FullUserRecord user =
+ getFullUserRecordLocked(UserHandle.getUserId(uid));
+ if (user != null) {
+ user.mPriorityStack.updateMediaButtonSessionIfNeeded();
+ }
+ }
+ }
+ });
mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
mContentResolver = getContext().getContentResolver();
mSettingsObserver = new SettingsObserver();
@@ -161,9 +177,10 @@ public class MediaSessionService extends SystemService implements Monitor {
user.mPriorityStack.onSessionStateChange(record);
if ((record.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
mGlobalPrioritySession = record;
+ user.pushAddressedPlayerChangedLocked();
}
+ mHandler.postSessionsChanged(record.getUserId());
}
- mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, record.getUserId(), 0);
}
/**
@@ -180,18 +197,14 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
- public void onSessionPlaystateChange(MediaSessionRecord record, int oldState, int newState) {
- boolean updateSessions = false;
+ public void onSessionPlaystateChanged(MediaSessionRecord record, int oldState, int newState) {
synchronized (mLock) {
FullUserRecord user = getFullUserRecordLocked(record.getUserId());
if (user == null || !user.mPriorityStack.contains(record)) {
Log.d(TAG, "Unknown session changed playback state. Ignoring.");
return;
}
- updateSessions = user.mPriorityStack.onPlaystateChange(record, oldState, newState);
- }
- if (updateSessions) {
- mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, record.getUserId(), 0);
+ user.mPriorityStack.onPlaystateChanged(record, oldState, newState);
}
}
@@ -332,6 +345,9 @@ public class MediaSessionService extends SystemService implements Monitor {
}
if (mGlobalPrioritySession == session) {
mGlobalPrioritySession = null;
+ if (session.isActive() && user != null) {
+ user.pushAddressedPlayerChangedLocked();
+ }
}
try {
@@ -340,8 +356,7 @@ public class MediaSessionService extends SystemService implements Monitor {
// ignore exceptions while destroying a session.
}
session.onDestroy();
-
- mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, session.getUserId(), 0);
+ mHandler.postSessionsChanged(session.getUserId());
}
private void enforcePackageName(String packageName, int uid) {
@@ -461,7 +476,7 @@ public class MediaSessionService extends SystemService implements Monitor {
}
final MediaSessionRecord session = new MediaSessionRecord(callerPid, callerUid, userId,
- callerPackageName, cb, tag, this, mHandler);
+ callerPackageName, cb, tag, this, mHandler.getLooper());
try {
cb.asBinder().linkToDeath(session, 0);
} catch (RemoteException e) {
@@ -469,8 +484,7 @@ public class MediaSessionService extends SystemService implements Monitor {
}
user.addSessionLocked(session);
-
- mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, userId, 0);
+ mHandler.postSessionsChanged(userId);
if (DEBUG) {
Log.d(TAG, "Created session for " + callerPackageName + " with tag " + tag);
@@ -496,10 +510,6 @@ public class MediaSessionService extends SystemService implements Monitor {
}
List<MediaSessionRecord> records = user.mPriorityStack.getActiveSessions(userId);
int size = records.size();
- if (size > 0 && records.get(0).isPlaybackActive(false)) {
- user.rememberMediaButtonReceiverLocked(records.get(0));
- }
- user.pushAddressedPlayerChangedLocked();
ArrayList<MediaSession.Token> tokens = new ArrayList<MediaSession.Token>();
for (int i = 0; i < size; i++) {
tokens.add(new MediaSession.Token(records.get(i).getControllerBinder()));
@@ -536,6 +546,22 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
+ /**
+ * Called when the media button receiver for the {@param record} is changed.
+ *
+ * @param record the media session whose media button receiver is updated.
+ */
+ public void onMediaButtonReceiverChanged(MediaSessionRecord record) {
+ synchronized (mLock) {
+ FullUserRecord user = getFullUserRecordLocked(record.getUserId());
+ MediaSessionRecord mediaButtonSession =
+ user.mPriorityStack.getMediaButtonSession();
+ if (record == mediaButtonSession) {
+ user.rememberMediaButtonReceiverLocked(mediaButtonSession);
+ }
+ }
+ }
+
private String getCallingPackageName(int uid) {
String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
if (packages != null && packages.length > 0) {
@@ -568,10 +594,10 @@ public class MediaSessionService extends SystemService implements Monitor {
* place makes more sense and increases the readability.</p>
* <p>The contents of this object is guarded by {@link #mLock}.
*/
- final class FullUserRecord {
+ final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener {
private static final String COMPONENT_NAME_USER_ID_DELIM = ",";
private final int mFullUserId;
- private final MediaSessionStack mPriorityStack = new MediaSessionStack();
+ private final MediaSessionStack mPriorityStack;
private PendingIntent mLastMediaButtonReceiver;
private ComponentName mRestoredMediaButtonReceiver;
private int mRestoredMediaButtonReceiverUserId;
@@ -588,6 +614,7 @@ public class MediaSessionService extends SystemService implements Monitor {
public FullUserRecord(int fullUserId) {
mFullUserId = fullUserId;
+ mPriorityStack = new MediaSessionStack(mAudioPlaybackMonitor, this);
// Restore the remembered media button receiver before the boot.
String mediaButtonReceiver = Settings.Secure.getStringForUser(mContentResolver,
Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId);
@@ -603,15 +630,14 @@ public class MediaSessionService extends SystemService implements Monitor {
}
public void destroySessionsForUserLocked(int userId) {
- List<MediaSessionRecord> sessions = mPriorityStack.getPriorityList(false, 0, userId);
+ List<MediaSessionRecord> sessions = mPriorityStack.getPriorityList(false, userId);
for (MediaSessionRecord session : sessions) {
MediaSessionService.this.destroySessionLocked(session);
}
}
public void addSessionLocked(MediaSessionRecord session) {
- mPriorityStack.addSession(session,
- mFullUserId == mFullUserIds.get(session.getUserId()));
+ mPriorityStack.addSession(session);
}
public void removeSessionLocked(MediaSessionRecord session) {
@@ -642,21 +668,41 @@ public class MediaSessionService extends SystemService implements Monitor {
mPriorityStack.dump(pw, indent);
}
- // Remember the media button receiver and keep it in the persistent storage.
- private void rememberMediaButtonReceiverLocked(MediaSessionRecord record) {
- PendingIntent receiver = record.getMediaButtonReceiver();
- if (receiver == null) {
- return;
+ @Override
+ public void onMediaButtonSessionChanged(MediaSessionRecord oldMediaButtonSession,
+ MediaSessionRecord newMediaButtonSession) {
+ if (DEBUG_KEY_EVENT) {
+ Log.d(TAG, "Media button session will be changed to " + newMediaButtonSession);
+ }
+ synchronized (mLock) {
+ if (oldMediaButtonSession != null) {
+ mHandler.postSessionsChanged(oldMediaButtonSession.getUserId());
+ }
+ if (newMediaButtonSession != null) {
+ rememberMediaButtonReceiverLocked(newMediaButtonSession);
+ mHandler.postSessionsChanged(newMediaButtonSession.getUserId());
+ }
+ pushAddressedPlayerChangedLocked();
}
+ }
+
+ // Remember media button receiver and keep it in the persistent storage.
+ public void rememberMediaButtonReceiverLocked(MediaSessionRecord record) {
+ PendingIntent receiver = record.getMediaButtonReceiver();
mLastMediaButtonReceiver = receiver;
- ComponentName component = receiver.getIntent().getComponent();
- if (component != null && record.getPackageName().equals(component.getPackageName())) {
- String componentName = component.flattenToString();
- Settings.Secure.putStringForUser(mContentResolver,
- Settings.System.MEDIA_BUTTON_RECEIVER,
- componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(),
- mFullUserId);
+ mRestoredMediaButtonReceiver = null;
+ String componentName = "";
+ if (receiver != null) {
+ ComponentName component = receiver.getIntent().getComponent();
+ if (component != null
+ && record.getPackageName().equals(component.getPackageName())) {
+ componentName = component.flattenToString();
+ }
}
+ Settings.Secure.putStringForUser(mContentResolver,
+ Settings.System.MEDIA_BUTTON_RECEIVER,
+ componentName + COMPONENT_NAME_USER_ID_DELIM + record.getUserId(),
+ mFullUserId);
}
private void pushAddressedPlayerChangedLocked() {
@@ -682,14 +728,8 @@ public class MediaSessionService extends SystemService implements Monitor {
}
private MediaSessionRecord getMediaButtonSessionLocked() {
- if (isGlobalPriorityActiveLocked()) {
- return mGlobalPrioritySession;
- }
- // If we don't have a media button receiver to fall back on
- // include non-playing sessions for dispatching.
- boolean useNotPlayingSessions = (mLastMediaButtonReceiver == null
- && mRestoredMediaButtonReceiver == null);
- return mPriorityStack.getDefaultMediaButtonSession(useNotPlayingSessions);
+ return isGlobalPriorityActiveLocked()
+ ? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession();
}
}
@@ -1262,6 +1302,7 @@ public class MediaSessionService extends SystemService implements Monitor {
for (int i = 0; i < count; i++) {
mUserRecords.valueAt(i).dumpLocked(pw, "");
}
+ mAudioPlaybackMonitor.dump(pw, "");
}
}
@@ -1390,7 +1431,7 @@ public class MediaSessionService extends SystemService implements Monitor {
PendingIntent receiver = mCurrentFullUserRecord.mLastMediaButtonReceiver;
if (DEBUG_KEY_EVENT) {
Log.d(TAG, "Sending " + keyEvent
- + " to the last known pendingIntent " + receiver);
+ + " to the last known PendingIntent " + receiver);
}
receiver.send(getContext(),
needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
@@ -1413,7 +1454,8 @@ public class MediaSessionService extends SystemService implements Monitor {
}
mediaButtonIntent.setComponent(receiver);
getContext().sendBroadcastAsUser(mediaButtonIntent,
- UserHandle.of(mCurrentFullUserRecord.mRestoredMediaButtonReceiverUserId));
+ UserHandle.of(mCurrentFullUserRecord
+ .mRestoredMediaButtonReceiverUserId));
if (mCurrentFullUserRecord.mCallback != null) {
mCurrentFullUserRecord.mCallback
.onMediaKeyEventDispatchedToMediaButtonReceiver(
@@ -1426,23 +1468,6 @@ public class MediaSessionService extends SystemService implements Monitor {
} catch (RemoteException e) {
Log.w(TAG, "Failed to send callback", e);
}
- } else {
- if (DEBUG) {
- Log.d(TAG, "Sending media key ordered broadcast");
- }
- if (needWakeLock) {
- mMediaEventWakeLock.acquire();
- }
- // Fallback to legacy behavior
- Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
- keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
- if (needWakeLock) {
- keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
- }
- // Send broadcast only to the full user.
- getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT,
- null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null);
}
}
@@ -1637,12 +1662,13 @@ public class MediaSessionService extends SystemService implements Monitor {
final class MessageHandler extends Handler {
private static final int MSG_SESSIONS_CHANGED = 1;
private static final int MSG_VOLUME_INITIAL_DOWN = 2;
+ private final SparseArray<Integer> mIntegerCache = new SparseArray<>();
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SESSIONS_CHANGED:
- pushSessionsChanged(msg.arg1);
+ pushSessionsChanged((int) msg.obj);
break;
case MSG_VOLUME_INITIAL_DOWN:
synchronized (mLock) {
@@ -1657,8 +1683,15 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
- public void post(int what, int arg1, int arg2) {
- obtainMessage(what, arg1, arg2).sendToTarget();
+ public void postSessionsChanged(int userId) {
+ // Use object instead of the arguments when posting message to remove pending requests.
+ Integer userIdInteger = mIntegerCache.get(userId);
+ if (userIdInteger == null) {
+ userIdInteger = Integer.valueOf(userId);
+ mIntegerCache.put(userId, userIdInteger);
+ }
+ removeMessages(MSG_SESSIONS_CHANGED, userIdInteger);
+ obtainMessage(MSG_SESSIONS_CHANGED, userIdInteger).sendToTarget();
}
}
}
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 8b8073454f8c..b0d8adcc122e 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -16,12 +16,13 @@
package com.android.server.media;
-import android.app.ActivityManager;
import android.media.session.MediaController.PlaybackInfo;
-import android.media.session.PlaybackState;
import android.media.session.MediaSession;
-import android.os.RemoteException;
+import android.media.session.PlaybackState;
+import android.os.Debug;
import android.os.UserHandle;
+import android.util.IntArray;
+import android.util.Log;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -33,6 +34,20 @@ import java.util.List;
* <p>This class isn't thread-safe. The caller should take care of the synchronization.
*/
class MediaSessionStack {
+ private static final boolean DEBUG = MediaSessionService.DEBUG;
+ private static final String TAG = "MediaSessionStack";
+
+ /**
+ * Listens the change in the media button session.
+ */
+ interface OnMediaButtonSessionChangedListener {
+ /**
+ * Called when the media button session is changed.
+ */
+ void onMediaButtonSessionChanged(MediaSessionRecord oldMediaButtonSession,
+ MediaSessionRecord newMediaButtonSession);
+ }
+
/**
* These are states that usually indicate the user took an action and should
* bump priority regardless of the old state.
@@ -51,57 +66,45 @@ class MediaSessionStack {
PlaybackState.STATE_CONNECTING,
PlaybackState.STATE_PLAYING };
- private final ArrayList<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>();
+ /**
+ * Sorted list of the media sessions.
+ * The session of which PlaybackState is changed to ALWAYS_PRIORITY_STATES or
+ * TRANSITION_PRIORITY_STATES comes first.
+ * @see #shouldUpdatePriority
+ */
+ private final List<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>();
+
+ private final AudioPlaybackMonitor mAudioPlaybackMonitor;
+ private final OnMediaButtonSessionChangedListener mOnMediaButtonSessionChangedListener;
+
+ /**
+ * The media button session which receives media key events.
+ * It could be null if the previous media buttion session is released.
+ */
+ private MediaSessionRecord mMediaButtonSession;
- // The last record that either entered one of the playing states or was
- // added.
- private MediaSessionRecord mLastInterestingRecord;
- private MediaSessionRecord mCachedButtonReceiver;
private MediaSessionRecord mCachedDefault;
private MediaSessionRecord mCachedVolumeDefault;
private ArrayList<MediaSessionRecord> mCachedActiveList;
- private ArrayList<MediaSessionRecord> mCachedTransportControlList;
- /**
- * Checks if a media session is created from the most recent app.
- *
- * @param record A media session record to be examined.
- * @return {@code true} if the media session's package name equals to the most recent app, false
- * otherwise.
- */
- private static boolean isFromMostRecentApp(MediaSessionRecord record) {
- try {
- List<ActivityManager.RecentTaskInfo> tasks =
- ActivityManager.getService().getRecentTasks(1,
- ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS |
- ActivityManager.RECENT_IGNORE_UNAVAILABLE |
- ActivityManager.RECENT_INCLUDE_PROFILES |
- ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList();
- if (tasks != null && !tasks.isEmpty()) {
- ActivityManager.RecentTaskInfo recentTask = tasks.get(0);
- if (recentTask.userId == record.getUserId() && recentTask.baseIntent != null) {
- return recentTask.baseIntent.getComponent().getPackageName()
- .equals(record.getPackageName());
- }
- }
- } catch (RemoteException e) {
- return false;
- }
- return false;
+ MediaSessionStack(AudioPlaybackMonitor monitor, OnMediaButtonSessionChangedListener listener) {
+ mAudioPlaybackMonitor = monitor;
+ mOnMediaButtonSessionChangedListener = listener;
}
/**
* Add a record to the priority tracker.
*
* @param record The record to add.
- * @param fromForegroundUser {@code true} if the session is created by the foreground user.
*/
- public void addSession(MediaSessionRecord record, boolean fromForegroundUser) {
+ public void addSession(MediaSessionRecord record) {
mSessions.add(record);
clearCache();
- if (fromForegroundUser && isFromMostRecentApp(record)) {
- mLastInterestingRecord = record;
- }
+
+ // Update the media button session.
+ // The added session could be the session from the package with the audio playback.
+ // This can happen if an app starts audio playback before creating media session.
+ updateMediaButtonSessionIfNeeded();
}
/**
@@ -111,6 +114,11 @@ class MediaSessionStack {
*/
public void removeSession(MediaSessionRecord record) {
mSessions.remove(record);
+ if (mMediaButtonSession == record) {
+ // When the media button session is gone, try to find the alternative media session
+ // in the media button session app.
+ onMediaSessionChangeInMediaButtonSessionApp();
+ }
clearCache();
}
@@ -122,32 +130,33 @@ class MediaSessionStack {
}
/**
- * Notify the priority tracker that a session's state changed.
+ * Notify the priority tracker that a session's playback state changed.
*
* @param record The record that changed.
* @param oldState Its old playback state.
* @param newState Its new playback state.
- * @return true if the priority order was updated, false otherwise.
*/
- public boolean onPlaystateChange(MediaSessionRecord record, int oldState, int newState) {
+ public void onPlaystateChanged(MediaSessionRecord record, int oldState, int newState) {
if (shouldUpdatePriority(oldState, newState)) {
mSessions.remove(record);
mSessions.add(0, record);
clearCache();
- // This becomes the last interesting record since it entered a
- // playing state
- mLastInterestingRecord = record;
- return true;
} else if (!MediaSession.isActiveState(newState)) {
// Just clear the volume cache when a state goes inactive
mCachedVolumeDefault = null;
}
- return false;
+
+ // In most cases, playback state isn't needed for finding media buttion session,
+ // but we only use it as a hint if an app has multiple local media sessions.
+ // In that case, we pick the media session whose PlaybackState matches
+ // the audio playback configuration.
+ if (mMediaButtonSession != null && mMediaButtonSession.getUid() == record.getUid()) {
+ onMediaSessionChangeInMediaButtonSessionApp();
+ }
}
/**
- * Handle any stack changes that need to occur in response to a session
- * state change. TODO add the old and new session state as params
+ * Handle the change in activeness for a session.
*
* @param record The record that changed.
*/
@@ -158,6 +167,81 @@ class MediaSessionStack {
}
/**
+ * Update the media button session if needed.
+ * <p>The media button session is the session that will receive the media button events.
+ * <p>We send the media button events to the lastly played app. If the app has the media
+ * session, the session will receive the media button events.
+ */
+ public void updateMediaButtonSessionIfNeeded() {
+ if (DEBUG) {
+ Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + Debug.getCallers(2));
+ }
+ IntArray audioPlaybackUids = mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
+ for (int i = 0; i < audioPlaybackUids.size(); i++) {
+ MediaSessionRecord mediaButtonSession =
+ findMediaButtonSession(audioPlaybackUids.get(i));
+ if (mediaButtonSession != null) {
+ // Found the media button session.
+ mAudioPlaybackMonitor.cleanUpAudioPlaybackUids(mediaButtonSession.getUid());
+ if (mMediaButtonSession != mediaButtonSession) {
+ mOnMediaButtonSessionChangedListener.onMediaButtonSessionChanged(
+ mMediaButtonSession, mediaButtonSession);
+ mMediaButtonSession = mediaButtonSession;
+ }
+ return;
+ }
+ }
+ }
+
+ /**
+ * Handle the change in a media session in the media button session app.
+ * <p>If the app has multiple media sessions, change in a media sesion in the app may change
+ * the media button session.
+ * @see #findMediaButtonSession
+ */
+ private void onMediaSessionChangeInMediaButtonSessionApp() {
+ MediaSessionRecord newMediaButtonSession =
+ findMediaButtonSession(mMediaButtonSession.getUid());
+ if (newMediaButtonSession != mMediaButtonSession) {
+ mOnMediaButtonSessionChangedListener.onMediaButtonSessionChanged(mMediaButtonSession,
+ newMediaButtonSession);
+ mMediaButtonSession = newMediaButtonSession;
+ }
+ }
+
+ /**
+ * Find the media button session with the given {@param uid}.
+ * If the app has multiple media sessions, the media session matches the audio playback state
+ * becomes the media button session.
+ *
+ * @return The media button session. Returns {@code null} if the app doesn't have a media
+ * session.
+ */
+ private MediaSessionRecord findMediaButtonSession(int uid) {
+ MediaSessionRecord mediaButtonSession = null;
+ for (MediaSessionRecord session : mSessions) {
+ // Since the media buttons come with the headset/speaker, users will expect changes in
+ // the headset/speaker when they press media buttons. So only consider local playback
+ // for the media button session.
+ if (uid == session.getUid()
+ && session.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
+ if (session.isPlaybackActive() ==
+ mAudioPlaybackMonitor.isPlaybackActive(session.getUid())) {
+ // If there's a media session whose PlaybackState matches
+ // the audio playback state, return it immediately.
+ return session;
+ }
+ if (mediaButtonSession == null) {
+ // Among the media sessions whose PlaybackState doesn't match
+ // the audio playback state, pick the top priority.
+ mediaButtonSession = session;
+ }
+ }
+ }
+ return mediaButtonSession;
+ }
+
+ /**
* Get the current priority sorted list of active sessions. The most
* important session is at index 0 and the least important at size - 1.
*
@@ -166,57 +250,29 @@ class MediaSessionStack {
*/
public ArrayList<MediaSessionRecord> getActiveSessions(int userId) {
if (mCachedActiveList == null) {
- mCachedActiveList = getPriorityList(true, 0, userId);
+ mCachedActiveList = getPriorityList(true, userId);
}
return mCachedActiveList;
}
/**
- * Get the highest priority session that can handle media buttons.
+ * Get the media button session which receives the media button events.
*
- * @param includeNotPlaying Return a non-playing session if nothing else is
- * available
- * @return The default media button session or null.
+ * @return The media button session or null.
*/
- public MediaSessionRecord getDefaultMediaButtonSession(boolean includeNotPlaying) {
- if (mCachedButtonReceiver != null) {
- return mCachedButtonReceiver;
- }
- ArrayList<MediaSessionRecord> records = getPriorityList(true,
- MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, UserHandle.USER_ALL);
- if (records.size() > 0) {
- MediaSessionRecord record = records.get(0);
- if (record.isPlaybackActive(false)) {
- // Since we're going to send a button event to this record make
- // it the last interesting one.
- mLastInterestingRecord = record;
- mCachedButtonReceiver = record;
- } else if (mLastInterestingRecord != null) {
- if (records.contains(mLastInterestingRecord)) {
- mCachedButtonReceiver = mLastInterestingRecord;
- } else {
- // That record is no longer used. Clear its reference.
- mLastInterestingRecord = null;
- }
- }
- if (includeNotPlaying && mCachedButtonReceiver == null) {
- // If we really want a record and we didn't find one yet use the
- // highest priority session even if it's not playing.
- mCachedButtonReceiver = record;
- }
- }
- return mCachedButtonReceiver;
+ public MediaSessionRecord getMediaButtonSession() {
+ return mMediaButtonSession;
}
public MediaSessionRecord getDefaultVolumeSession() {
if (mCachedVolumeDefault != null) {
return mCachedVolumeDefault;
}
- ArrayList<MediaSessionRecord> records = getPriorityList(true, 0, UserHandle.USER_ALL);
+ ArrayList<MediaSessionRecord> records = getPriorityList(true, UserHandle.USER_ALL);
int size = records.size();
for (int i = 0; i < size; i++) {
MediaSessionRecord record = records.get(i);
- if (record.isPlaybackActive(false)) {
+ if (record.isPlaybackActive()) {
mCachedVolumeDefault = record;
return record;
}
@@ -225,7 +281,7 @@ class MediaSessionStack {
}
public MediaSessionRecord getDefaultRemoteSession(int userId) {
- ArrayList<MediaSessionRecord> records = getPriorityList(true, 0, userId);
+ ArrayList<MediaSessionRecord> records = getPriorityList(true, userId);
int size = records.size();
for (int i = 0; i < size; i++) {
@@ -238,9 +294,10 @@ class MediaSessionStack {
}
public void dump(PrintWriter pw, String prefix) {
- ArrayList<MediaSessionRecord> sortedSessions = getPriorityList(false, 0,
+ ArrayList<MediaSessionRecord> sortedSessions = getPriorityList(false,
UserHandle.USER_ALL);
int count = sortedSessions.size();
+ pw.println(prefix + "Media button session is " + mMediaButtonSession);
pw.println(prefix + "Sessions Stack - have " + count + " sessions:");
String indent = prefix + " ";
for (int i = 0; i < count; i++) {
@@ -252,22 +309,23 @@ class MediaSessionStack {
/**
* Get a priority sorted list of sessions. Can filter to only return active
- * sessions or sessions with specific flags.
+ * sessions or sessions.
+ * <p>Here's the priority order.
+ * <li>System priority session (session with FLAG_EXCLUSIVE_GLOBAL_PRIORITY)</li>
+ * <li>Active sessions whose PlaybackState is active</li>
+ * <li>Active sessions whose PlaybackState is inactive</li>
+ * <li>Inactive sessions</li>
*
* @param activeOnly True to only return active sessions, false to return
* all sessions.
- * @param withFlags Only return sessions with all the specified flags set. 0
- * returns all sessions.
* @param userId The user to get sessions for. {@link UserHandle#USER_ALL}
* will return sessions for all users.
* @return The priority sorted list of sessions.
*/
- public ArrayList<MediaSessionRecord> getPriorityList(boolean activeOnly, int withFlags,
- int userId) {
+ public ArrayList<MediaSessionRecord> getPriorityList(boolean activeOnly, int userId) {
ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>();
- int lastLocalIndex = 0;
+ int lastPlaybackActiveIndex = 0;
int lastActiveIndex = 0;
- int lastPublishedIndex = 0;
int size = mSessions.size();
for (int i = 0; i < size; i++) {
@@ -277,10 +335,7 @@ class MediaSessionStack {
// Filter out sessions for the wrong user
continue;
}
- if ((session.getFlags() & withFlags) != withFlags) {
- // Filter out sessions with the wrong flags
- continue;
- }
+
if (!session.isActive()) {
if (!activeOnly) {
// If we're getting unpublished as well always put them at
@@ -294,28 +349,13 @@ class MediaSessionStack {
// System priority sessions are special and always go at the
// front. We expect there to only be one of these at a time.
result.add(0, session);
- lastLocalIndex++;
+ lastPlaybackActiveIndex++;
+ lastActiveIndex++;
+ } else if (session.isPlaybackActive()) {
+ result.add(lastPlaybackActiveIndex++, session);
lastActiveIndex++;
- lastPublishedIndex++;
- } else if (session.isPlaybackActive(true)) {
- // TODO this with real local route check
- if (true) {
- // Active local sessions get top priority
- result.add(lastLocalIndex, session);
- lastLocalIndex++;
- lastActiveIndex++;
- lastPublishedIndex++;
- } else {
- // Then active remote sessions
- result.add(lastActiveIndex, session);
- lastActiveIndex++;
- lastPublishedIndex++;
- }
} else {
- // inactive sessions go at the end in order of whoever last did
- // something.
- result.add(lastPublishedIndex, session);
- lastPublishedIndex++;
+ result.add(lastActiveIndex++, session);
}
}
@@ -345,8 +385,6 @@ class MediaSessionStack {
private void clearCache() {
mCachedDefault = null;
mCachedVolumeDefault = null;
- mCachedButtonReceiver = null;
mCachedActiveList = null;
- mCachedTransportControlList = null;
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index fc45344b2f4d..f180c5089aa1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -75,6 +75,9 @@ import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
+import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
+import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
+import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -141,6 +144,7 @@ import android.os.IDeviceIdleController;
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.MessageQueue.IdleHandler;
+import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.Process;
@@ -153,6 +157,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -174,12 +179,14 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.power.BatterySaverPolicy.ServiceType;
@@ -204,6 +211,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Calendar;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -310,6 +318,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int MSG_SET_FIREWALL_RULES = 14;
private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
+ private static final int UID_MSG_STATE_CHANGED = 100;
+ private static final int UID_MSG_GONE = 101;
+
private final Context mContext;
private final IActivityManager mActivityManager;
private final INetworkStatsService mNetworkStats;
@@ -317,6 +328,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private UsageStatsManagerInternal mUsageStats;
private final TrustedTime mTime;
private final UserManager mUserManager;
+ private final CarrierConfigManager mCarrierConfigManager;
private IConnectivityManager mConnManager;
private INotificationManager mNotifManager;
@@ -420,6 +432,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mListeners = new RemoteCallbackList<>();
final Handler mHandler;
+ @VisibleForTesting
+ public final Handler mUidEventHandler;
+
+ private final ServiceThread mUidEventThread;
@GuardedBy("allLocks")
private final AtomicFile mPolicyFile;
@@ -465,12 +481,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Context.DEVICE_IDLE_CONTROLLER));
mTime = checkNotNull(time, "missing TrustedTime");
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
mIPm = pm;
HandlerThread thread = new HandlerThread(TAG);
thread.start();
mHandler = new Handler(thread.getLooper(), mHandlerCallback);
+ // We create another thread for the UID events, which are more time-critical.
+ mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
+ /*allowIo=*/ false);
+ mUidEventThread.start();
+ mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
+
mSuppressDefaultPolicy = suppressDefaultPolicy;
mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
@@ -743,6 +766,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
WifiManager.NETWORK_STATE_CHANGED_ACTION);
mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
+ // listen for carrier config changes to update data cycle information
+ final IntentFilter carrierConfigFilter = new IntentFilter(
+ ACTION_CARRIER_CONFIG_CHANGED);
+ mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
+
mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
// tell systemReady() that the service has been initialized
initCompleteSignal.countDown();
@@ -774,26 +802,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState,
long procStateSeq) throws RemoteException {
- Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
- try {
- synchronized (mUidRulesFirstLock) {
- // We received a uid state change callback, add it to the history so that it
- // will be useful for debugging.
- mObservedHistory.addProcStateSeqUL(uid, procStateSeq);
- // Now update the network policy rules as per the updated uid state.
- updateUidStateUL(uid, procState);
- // Updating the network rules is done, so notify AMS about this.
- mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
- }
+ mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
+ uid, procState, procStateSeq).sendToTarget();
}
@Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
- synchronized (mUidRulesFirstLock) {
- removeUidStateUL(uid);
- }
+ mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
}
@Override public void onUidActive(int uid) throws RemoteException {
@@ -1293,6 +1307,213 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
};
/**
+ * Update mobile policies with data cycle information from {@link CarrierConfigManager}
+ * if necessary.
+ *
+ * @param subId that has its associated NetworkPolicy updated if necessary
+ * @return if any policies were updated
+ */
+ private boolean maybeUpdateMobilePolicyCycleNL(int subId) {
+ if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleNL()");
+ final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+
+ if (config == null) {
+ return false;
+ }
+
+ boolean policyUpdated = false;
+ final String subscriberId = TelephonyManager.from(mContext).getSubscriberId(subId);
+
+ // find and update the mobile NetworkPolicy for this subscriber id
+ final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
+ TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
+ for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
+ final NetworkTemplate template = mNetworkPolicy.keyAt(i);
+ if (template.matches(probeIdent)) {
+ NetworkPolicy policy = mNetworkPolicy.valueAt(i);
+
+ // only update the policy if the user didn't change any of the defaults.
+ if (!policy.inferred) {
+ // TODO: inferred could be split, so that if a user changes their data limit or
+ // warning, it doesn't prevent their cycle date from being updated.
+ if (LOGD) Slog.v(TAG, "Didn't update NetworkPolicy because policy.inferred");
+ continue;
+ }
+
+ final int cycleDay = getCycleDayFromCarrierConfig(config, policy.cycleDay);
+ final long warningBytes = getWarningBytesFromCarrierConfig(config,
+ policy.warningBytes);
+ final long limitBytes = getLimitBytesFromCarrierConfig(config,
+ policy.limitBytes);
+
+ if (policy.cycleDay == cycleDay &&
+ policy.warningBytes == warningBytes &&
+ policy.limitBytes == limitBytes) {
+ continue;
+ }
+
+ policyUpdated = true;
+ policy.cycleDay = cycleDay;
+ policy.warningBytes = warningBytes;
+ policy.limitBytes = limitBytes;
+
+ if (LOGD) {
+ Slog.d(TAG, "Updated NetworkPolicy " + policy + " which matches subscriber "
+ + NetworkIdentity.scrubSubscriberId(subscriberId)
+ + " from CarrierConfigManager");
+ }
+ }
+ }
+
+ return policyUpdated;
+ }
+
+ /**
+ * Returns the cycle day that should be used for a mobile NetworkPolicy.
+ *
+ * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
+ * to do so, it returns the fallback value.
+ *
+ * @param config The CarrierConfig to read the value from.
+ * @param fallbackCycleDay to return if the CarrierConfig can't be read.
+ * @return cycleDay to use in the mobile NetworkPolicy.
+ */
+ @VisibleForTesting
+ public int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
+ int fallbackCycleDay) {
+ if (config == null) {
+ return fallbackCycleDay;
+ }
+ int cycleDay =
+ config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
+ if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
+ return fallbackCycleDay;
+ }
+ // validate cycleDay value
+ final Calendar cal = Calendar.getInstance();
+ if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) ||
+ cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) {
+ Slog.e(TAG, "Invalid date in "
+ + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay);
+ return fallbackCycleDay;
+ }
+ return cycleDay;
+ }
+
+ /**
+ * Returns the warning bytes that should be used for a mobile NetworkPolicy.
+ *
+ * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
+ * to do so, it returns the fallback value.
+ *
+ * @param config The CarrierConfig to read the value from.
+ * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
+ * @return warningBytes to use in the mobile NetworkPolicy.
+ */
+ @VisibleForTesting
+ public long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
+ long fallbackWarningBytes) {
+ if (config == null) {
+ return fallbackWarningBytes;
+ }
+ long warningBytes =
+ config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
+
+ if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
+ return WARNING_DISABLED;
+ } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
+ return getPlatformDefaultWarningBytes();
+ } else if (warningBytes < 0) {
+ Slog.e(TAG, "Invalid value in "
+ + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a "
+ + "non-negative value but got: " + warningBytes);
+ return fallbackWarningBytes;
+ }
+
+ return warningBytes;
+ }
+
+ /**
+ * Returns the limit bytes that should be used for a mobile NetworkPolicy.
+ *
+ * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
+ * to do so, it returns the fallback value.
+ *
+ * @param config The CarrierConfig to read the value from.
+ * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
+ * @return limitBytes to use in the mobile NetworkPolicy.
+ */
+ @VisibleForTesting
+ public long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
+ long fallbackLimitBytes) {
+ if (config == null) {
+ return fallbackLimitBytes;
+ }
+ long limitBytes =
+ config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
+
+ if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
+ return LIMIT_DISABLED;
+ } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
+ return getPlatformDefaultLimitBytes();
+ } else if (limitBytes < 0) {
+ Slog.e(TAG, "Invalid value in "
+ + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a "
+ + "non-negative value but got: " + limitBytes);
+ return fallbackLimitBytes;
+ }
+ return limitBytes;
+ }
+
+ /**
+ * Receiver that watches for {@link CarrierConfigManager} to be changed.
+ */
+ private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
+ // broadcast is protected and can't be spoofed. Runs on a background handler thread.
+
+ if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
+ return;
+ }
+ final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
+ final TelephonyManager tele = TelephonyManager.from(mContext);
+ final String subscriberId = tele.getSubscriberId(subId);
+
+ maybeRefreshTrustedTime();
+ synchronized (mUidRulesFirstLock) {
+ synchronized (mNetworkPoliciesSecondLock) {
+ final boolean added = ensureActiveMobilePolicyNL(subId, subscriberId);
+ if (added) return;
+ final boolean updated = maybeUpdateMobilePolicyCycleNL(subId);
+ if (!updated) return;
+ // update network and notification rules, as the data cycle changed and it's
+ // possible that we should be triggering warnings/limits now
+ handleNetworkPoliciesUpdateAL(true);
+ }
+ }
+ }
+ };
+
+ /**
+ * Handles all tasks that need to be run after a new network policy has been set, or an existing
+ * one has been updated.
+ *
+ * @param shouldNormalizePolicies true iff network policies need to be normalized after the
+ * update.
+ */
+ void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
+ if (shouldNormalizePolicies) {
+ normalizePoliciesNL();
+ }
+ updateNetworkEnabledNL();
+ updateNetworkRulesNL();
+ updateNotificationsNL();
+ writePolicyAL();
+ }
+
+ /**
* Proactively control network data connections when they exceed
* {@link NetworkPolicy#limitBytes}.
*/
@@ -1517,11 +1738,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int[] subIds = sub.getActiveSubscriptionIdList();
for (int subId : subIds) {
final String subscriberId = tele.getSubscriberId(subId);
- ensureActiveMobilePolicyNL(subscriberId);
+ ensureActiveMobilePolicyNL(subId, subscriberId);
}
}
- private void ensureActiveMobilePolicyNL(String subscriberId) {
+ /**
+ * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
+ * have at least a default mobile policy defined.
+ *
+ * @param subId to build a default policy for
+ * @param subscriberId that we check for an existing policy
+ * @return true if a mobile network policy was added, or false one already existed.
+ */
+ private boolean ensureActiveMobilePolicyNL(int subId, String subscriberId) {
// Poke around to see if we already have a policy
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
@@ -1532,33 +1761,51 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Slog.d(TAG, "Found template " + template + " which matches subscriber "
+ NetworkIdentity.scrubSubscriberId(subscriberId));
}
- return;
+ return false;
}
}
Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
+ "; generating default policy");
+ final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId);
+ addNetworkPolicyNL(policy);
+ return true;
+ }
- // Build default mobile policy, and assume usage cycle starts today
+ private long getPlatformDefaultWarningBytes() {
final int dataWarningConfig = mContext.getResources().getInteger(
com.android.internal.R.integer.config_networkPolicyDefaultWarning);
- final long warningBytes;
if (dataWarningConfig == WARNING_DISABLED) {
- warningBytes = WARNING_DISABLED;
+ return WARNING_DISABLED;
} else {
- warningBytes = dataWarningConfig * MB_IN_BYTES;
+ return dataWarningConfig * MB_IN_BYTES;
}
+ }
+ private long getPlatformDefaultLimitBytes() {
+ return LIMIT_DISABLED;
+ }
+
+ @VisibleForTesting
+ public NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
+ PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+
+ // assume usage cycle starts today
final Time time = new Time();
time.setToNow();
- final int cycleDay = time.monthDay;
final String cycleTimezone = time.timezone;
+ final int cycleDay = getCycleDayFromCarrierConfig(config, time.monthDay);
+ final long warningBytes = getWarningBytesFromCarrierConfig(config,
+ getPlatformDefaultWarningBytes());
+ final long limitBytes = getLimitBytesFromCarrierConfig(config,
+ getPlatformDefaultLimitBytes());
+
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone,
- warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
- addNetworkPolicyNL(policy);
+ warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
+ return policy;
}
private void readPolicyAL() {
@@ -2026,10 +2273,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
normalizePoliciesNL(policies);
- updateNetworkEnabledNL();
- updateNetworkRulesNL();
- updateNotificationsNL();
- writePolicyAL();
+ handleNetworkPoliciesUpdateAL(false);
}
}
} finally {
@@ -2126,11 +2370,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
throw new IllegalArgumentException("unexpected type");
}
- normalizePoliciesNL();
- updateNetworkEnabledNL();
- updateNetworkRulesNL();
- updateNotificationsNL();
- writePolicyAL();
+ handleNetworkPoliciesUpdateAL(true);
}
}
}
@@ -2361,11 +2601,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mNetworkPolicy.valueAt(i).clearSnooze();
}
- normalizePoliciesNL();
- updateNetworkEnabledNL();
- updateNetworkRulesNL();
- updateNotificationsNL();
- writePolicyAL();
+ handleNetworkPoliciesUpdateAL(true);
fout.println("Cleared snooze timestamps");
return;
@@ -3317,7 +3553,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
- private Handler.Callback mHandlerCallback = new Handler.Callback() {
+ private final Handler.Callback mHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
@@ -3441,9 +3677,61 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
}
+ };
+
+ private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case UID_MSG_STATE_CHANGED: {
+ final int uid = msg.arg1;
+ final int procState = msg.arg2;
+ final long procStateSeq = (Long) msg.obj;
+
+ handleUidChanged(uid, procState, procStateSeq);
+ return true;
+ }
+ case UID_MSG_GONE: {
+ final int uid = msg.arg1;
+ handleUidGone(uid);
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+ }
};
+ void handleUidChanged(int uid, int procState, long procStateSeq) {
+ Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
+ try {
+ synchronized (mUidRulesFirstLock) {
+ // We received a uid state change callback, add it to the history so that it
+ // will be useful for debugging.
+ mObservedHistory.addProcStateSeqUL(uid, procStateSeq);
+ // Now update the network policy rules as per the updated uid state.
+ updateUidStateUL(uid, procState);
+ // Updating the network rules is done, so notify AMS about this.
+ mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
+ }
+ }
+
+ void handleUidGone(int uid) {
+ Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
+ try {
+ synchronized (mUidRulesFirstLock) {
+ removeUidStateUL(uid);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
+ }
+ }
+
private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
final PackageManager pm = mContext.getPackageManager();
final String[] packages = pm.getPackagesForUid(uid);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ede5a5e8e337..7468b956af4e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -90,6 +90,7 @@ import android.media.AudioManagerInternal;
import android.media.IRingtonePlayer;
import android.net.Uri;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -3126,8 +3127,9 @@ public class NotificationManagerService extends SystemService {
+ ", incomingUserId=" + incomingUserId
+ ", notificationUid=" + notificationUid
+ ", notification=" + notification;
- // STOPSHIP TODO: should throw instead of logging.
- // throw new IllegalArgumentException(noChannelStr);
+ if (Build.IS_DEBUGGABLE) {
+ throw new IllegalArgumentException(noChannelStr);
+ }
Log.e(TAG, noChannelStr);
return;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index db133f876d17..5bdef9ea7d49 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -102,7 +102,8 @@ final class OverlayManagerServiceImpl {
if (oi == null) {
// This overlay does not exist in our settings.
- if (mDefaultOverlays.contains(overlayPackage.packageName)) {
+ if (overlayPackage.isStaticOverlay ||
+ mDefaultOverlays.contains(overlayPackage.packageName)) {
// Enable this overlay by default.
mSettings.setEnabled(overlayPackage.packageName, newUserId, true);
}
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 126f8c408e22..6245ffc64009 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -135,16 +135,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
}
for (PackageParser.Package p : important) {
- // Make sure that core apps are optimized according to their own "reason".
- // If the core apps are not preopted in the B OTA, and REASON_AB_OTA is not speed
- // (by default is speed-profile) they will be interepreted/JITed. This in itself is
- // not a problem as we will end up doing profile guided compilation. However, some
- // core apps may be loaded by system server which doesn't JIT and we need to make
- // sure we don't interpret-only
- int compilationReason = p.coreApp
- ? PackageManagerService.REASON_CORE_APP
- : PackageManagerService.REASON_AB_OTA;
- mDexoptCommands.addAll(generatePackageDexopts(p, compilationReason));
+ mDexoptCommands.addAll(generatePackageDexopts(p, PackageManagerService.REASON_AB_OTA));
}
for (PackageParser.Package p : others) {
// We assume here that there are no core apps left.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8cc937502592..f633d7d940a1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -537,12 +537,9 @@ public class PackageManagerService extends IPackageManager.Stub {
public static final int REASON_INSTALL = 2;
public static final int REASON_BACKGROUND_DEXOPT = 3;
public static final int REASON_AB_OTA = 4;
- public static final int REASON_NON_SYSTEM_LIBRARY = 5;
- public static final int REASON_SHARED_APK = 6;
- public static final int REASON_FORCED_DEXOPT = 7;
- public static final int REASON_CORE_APP = 8;
+ public static final int REASON_FORCED_DEXOPT = 5;
- public static final int REASON_LAST = REASON_CORE_APP;
+ public static final int REASON_LAST = REASON_FORCED_DEXOPT;
/** All dangerous permission names in the same order as the events in MetricsEvent */
private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
@@ -653,6 +650,11 @@ public class PackageManagerService extends IPackageManager.Stub {
final ArrayMap<String, Set<String>> mKnownCodebase =
new ArrayMap<String, Set<String>>();
+ // Keys are isolated uids and values are the uid of the application
+ // that created the isolated proccess.
+ @GuardedBy("mPackages")
+ final SparseIntArray mIsolatedOwners = new SparseIntArray();
+
// List of APK paths to load for each user and package. This data is never
// persisted by the package manager. Instead, the overlay manager will
// ensure the data is up-to-date in runtime.
@@ -842,6 +844,8 @@ public class PackageManagerService extends IPackageManager.Stub {
/** Component used to install ephemeral applications */
ComponentName mInstantAppInstallerComponent;
+ /** Component used to show resolver settings for Instant Apps */
+ ComponentName mInstantAppResolverSettingsComponent;
ActivityInfo mInstantAppInstallerActivity;
final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
@@ -2376,59 +2380,6 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
}
- final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
- final String[] dexCodeInstructionSets =
- getDexCodeInstructionSets(
- allInstructionSets.toArray(new String[allInstructionSets.size()]));
-
- /**
- * Ensure all external libraries have had dexopt run on them.
- */
- if (mSharedLibraries.size() > 0) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
- // NOTE: For now, we're compiling these system "shared libraries"
- // (and framework jars) into all available architectures. It's possible
- // to compile them only when we come across an app that uses them (there's
- // already logic for that in scanPackageLI) but that adds some complexity.
- for (String dexCodeInstructionSet : dexCodeInstructionSets) {
- final int libCount = mSharedLibraries.size();
- for (int i = 0; i < libCount; i++) {
- SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
- final int versionCount = versionedLib.size();
- for (int j = 0; j < versionCount; j++) {
- SharedLibraryEntry libEntry = versionedLib.valueAt(j);
- final String libPath = libEntry.path != null
- ? libEntry.path : libEntry.apk;
- if (libPath == null) {
- continue;
- }
- try {
- // Shared libraries do not have profiles so we perform a full
- // AOT compilation (if needed).
- int dexoptNeeded = DexFile.getDexOptNeeded(
- libPath, dexCodeInstructionSet,
- getCompilerFilterForReason(REASON_SHARED_APK),
- false /* newProfile */);
- if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
- mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*",
- dexCodeInstructionSet, dexoptNeeded, null,
- DEXOPT_PUBLIC,
- getCompilerFilterForReason(REASON_SHARED_APK),
- StorageManager.UUID_PRIVATE_INTERNAL,
- PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK);
- }
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "Library not found: " + libPath);
- } catch (IOException | InstallerException e) {
- Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? "
- + e.getMessage());
- }
- }
- }
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
final VersionInfo ver = mSettings.getInternalVersion();
@@ -2817,41 +2768,6 @@ public class PackageManagerService extends IPackageManager.Stub {
mSettings.writeLPr();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
- // early on (before the package manager declares itself as early) because other
- // components in the system server might ask for package contexts for these apps.
- //
- // Note that "onlyCore" in this context means the system is encrypted or encrypting
- // (i.e, that the data partition is unavailable).
- if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
- long start = System.nanoTime();
- List<PackageParser.Package> coreApps = new ArrayList<>();
- for (PackageParser.Package pkg : mPackages.values()) {
- if (pkg.coreApp) {
- coreApps.add(pkg);
- }
- }
-
- int[] stats = performDexOptUpgrade(coreApps, false,
- getCompilerFilterForReason(REASON_CORE_APP));
-
- final int elapsedTimeSeconds =
- (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
- MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
-
- if (DEBUG_DEXOPT) {
- Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
- stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
- }
-
-
- // TODO: Should we log these stats to tron too ?
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
- }
-
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
@@ -2890,6 +2806,7 @@ public class PackageManagerService extends IPackageManager.Stub {
mInstantAppResolverConnection = null;
}
updateInstantAppInstallerLocked();
+ mInstantAppResolverSettingsComponent = getEphemeralResolverSettingsLPr();
// Read and update the usage of dex files.
// Do this at the end of PM init so that all the packages have their
@@ -3196,6 +3113,37 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ private @Nullable ComponentName getEphemeralResolverSettingsLPr() {
+ final Intent intent = new Intent(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ final int resolveFlags =
+ MATCH_DIRECT_BOOT_AWARE
+ | MATCH_DIRECT_BOOT_UNAWARE
+ | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
+ final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
+ resolveFlags, UserHandle.USER_SYSTEM);
+ Iterator<ResolveInfo> iter = matches.iterator();
+ while (iter.hasNext()) {
+ final ResolveInfo rInfo = iter.next();
+ final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
+ if (ps != null) {
+ final PermissionsState permissionsState = ps.getPermissionsState();
+ if (permissionsState.hasPermission(Manifest.permission.ACCESS_INSTANT_APPS, 0)) {
+ continue;
+ }
+ }
+ iter.remove();
+ }
+ if (matches.size() == 0) {
+ return null;
+ } else if (matches.size() == 1) {
+ return matches.get(0).getComponentInfo().getComponentName();
+ } else {
+ throw new RuntimeException(
+ "There must be at most one ephemeral resolver settings; found " + matches);
+ }
+ }
+
private void primeDomainVerificationsLPw(int userId) {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.d(TAG, "Priming domain verifications in user " + userId);
@@ -5788,6 +5736,10 @@ public class PackageManagerService extends IPackageManager.Stub {
return false;
}
if (ps.getInstantApp(userId)) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "DENY instant app installed;"
+ + " pkg: " + packageName);
+ }
return false;
}
}
@@ -6174,6 +6126,10 @@ public class PackageManagerService extends IPackageManager.Stub {
* instant, returns {@code null}.
*/
private String getInstantAppPackageName(int callingUid) {
+ // If the caller is an isolated app use the owner's uid for the lookup.
+ if (Process.isIsolated(callingUid)) {
+ callingUid = mIsolatedOwners.get(callingUid);
+ }
final int appId = UserHandle.getAppId(callingUid);
synchronized (mPackages) {
final Object obj = mSettings.getUserIdLPr(appId);
@@ -6267,7 +6223,6 @@ public class PackageManagerService extends IPackageManager.Stub {
intent, resolvedType, flags, userId), userId);
addEphemeral = !ephemeralDisabled
&& isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
-
// Check for cross profile results.
boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
xpResolveInfo = queryCrossProfileIntents(
@@ -6323,7 +6278,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} else {
// the caller wants to resolve for a particular package; however, there
// were no installed results, so, try to find an ephemeral result
- addEphemeral = !ephemeralDisabled
+ addEphemeral = !ephemeralDisabled
&& isEphemeralAllowed(
intent, null /*result*/, userId, true /*skipPackageCheck*/);
result = new ArrayList<ResolveInfo>();
@@ -7347,17 +7302,22 @@ public class PackageManagerService extends IPackageManager.Stub {
if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
return false;
}
+ int uid = Binder.getCallingUid();
+ if (Process.isIsolated(uid)) {
+ uid = mIsolatedOwners.get(uid);
+ }
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
+ PackageParser.Package pkg = mPackages.get(packageName);
final boolean returnAllowed =
ps != null
- && (isCallerSameApp(packageName)
+ && (isCallerSameApp(packageName, uid)
|| mContext.checkCallingOrSelfPermission(
android.Manifest.permission.ACCESS_INSTANT_APPS)
== PERMISSION_GRANTED
|| mInstantAppRegistry.isInstantAccessGranted(
- userId, UserHandle.getAppId(Binder.getCallingUid()), ps.appId));
+ userId, UserHandle.getAppId(uid), ps.appId));
if (returnAllowed) {
return ps.getInstantApp(userId);
}
@@ -7374,7 +7334,7 @@ public class PackageManagerService extends IPackageManager.Stub {
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, false /* checkShell */,
"getInstantAppCookie");
- if (!isCallerSameApp(packageName)) {
+ if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
return null;
}
synchronized (mPackages) {
@@ -7392,7 +7352,7 @@ public class PackageManagerService extends IPackageManager.Stub {
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, true /* checkShell */,
"setInstantAppCookie");
- if (!isCallerSameApp(packageName)) {
+ if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
return false;
}
synchronized (mPackages) {
@@ -7420,10 +7380,10 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private boolean isCallerSameApp(String packageName) {
+ private boolean isCallerSameApp(String packageName, int uid) {
PackageParser.Package pkg = mPackages.get(packageName);
return pkg != null
- && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
+ && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
}
@Override
@@ -8460,19 +8420,23 @@ public class PackageManagerService extends IPackageManager.Stub {
? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
: mPackageDexOptimizer;
- // Optimize all dependencies first. Note: we ignore the return value and march on
+ // Dexopt all dependencies first. Note: we ignore the return value and march on
// on errors.
+ // Note that we are going to call performDexOpt on those libraries as many times as
+ // they are referenced in packages. When we do a batch of performDexOpt (for example
+ // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
+ // and the first package that uses the library will dexopt it. The
+ // others will see that the compiled code for the library is up to date.
Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
if (!deps.isEmpty()) {
for (PackageParser.Package depPackage : deps) {
// TODO: Analyze and investigate if we (should) profile libraries.
- // Currently this will do a full compilation of the library by default.
pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
false /* checkProfiles */,
- getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
+ targetCompilerFilter,
getOrCreateCompilerPackageStats(depPackage),
- mDexManager.isUsedByOtherApps(p.packageName));
+ true /* isUsedByOtherApps */);
}
}
return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
@@ -12950,7 +12914,7 @@ public class PackageManagerService extends IPackageManager.Stub {
IActivityManager am = ActivityManager.getService();
if (am != null) {
try {
- am.startService(null, intent, null, -1, null, mContext.getOpPackageName(),
+ am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
}
@@ -16884,6 +16848,15 @@ public class PackageManagerService extends IPackageManager.Stub {
return;
}
+ // Shared libraries for the package need to be updated.
+ synchronized (mPackages) {
+ try {
+ updateSharedLibrariesLPr(pkg, null);
+ } catch (PackageManagerException e) {
+ Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+ }
+ }
+
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
// Do not run PackageDexOptimizer through the local performDexOpt
// method because `pkg` may not be in `mPackages` yet.
@@ -16932,6 +16905,7 @@ public class PackageManagerService extends IPackageManager.Stub {
args.user, installerPackageName, volumeUuid, res, args.installReason);
}
}
+
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
@@ -23073,6 +23047,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
@Override
+ public boolean isInstantAppInstallerComponent(ComponentName component) {
+ synchronized (mPackages) {
+ return component != null && component.equals(mInstantAppInstallerComponent);
+ }
+ }
+
+ @Override
public void pruneInstantApps() {
synchronized (mPackages) {
mInstantAppRegistry.pruneInstantAppsLPw();
@@ -23176,6 +23157,21 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
return resolveIntentInternal(
intent, resolvedType, flags, userId, true /*includeInstantApp*/);
}
+
+
+ @Override
+ public void addIsolatedUid(int isolatedUid, int ownerUid) {
+ synchronized (mPackages) {
+ mIsolatedOwners.put(isolatedUid, ownerUid);
+ }
+ }
+
+ @Override
+ public void removeIsolatedUid(int isolatedUid) {
+ synchronized (mPackages) {
+ mIsolatedOwners.delete(isolatedUid);
+ }
+ }
}
@Override
@@ -23313,4 +23309,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
}
+
+ @Override
+ public ComponentName getInstantAppResolverSettingsComponent() {
+ return mInstantAppResolverSettingsComponent;
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 0634dac8de4e..f6872e4373fd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,8 +26,7 @@ import dalvik.system.DexFile;
public class PackageManagerServiceCompilerMapping {
// Names for compilation reasons.
static final String REASON_STRINGS[] = {
- "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk",
- "forced-dexopt", "core-app"
+ "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "forced-dexopt"
};
// Static block to ensure the strings array is of the right length.
@@ -57,7 +56,6 @@ public class PackageManagerServiceCompilerMapping {
// Ensure that some reasons are not mapped to profile-guided filters.
switch (reason) {
- case PackageManagerService.REASON_SHARED_APK:
case PackageManagerService.REASON_FORCED_DEXOPT:
if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) {
throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, "
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a31258c39341..8ecf6f74bc8f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3389,6 +3389,12 @@ public class UserManagerService extends IUserManager.Stub {
pw.print(" <partial>");
}
pw.println();
+ pw.print(" State: ");
+ final int state;
+ synchronized (mUserStates) {
+ state = mUserStates.get(userId, -1);
+ }
+ pw.println(UserState.stateToString(state));
pw.print(" Created: ");
if (userInfo.creationTime == 0) {
pw.println("<unknown>");
diff --git a/services/core/java/com/android/server/storage/AppFuseBridge.java b/services/core/java/com/android/server/storage/AppFuseBridge.java
index 904d9159e578..6a0b6489f470 100644
--- a/services/core/java/com/android/server/storage/AppFuseBridge.java
+++ b/services/core/java/com/android/server/storage/AppFuseBridge.java
@@ -21,7 +21,9 @@ import android.system.ErrnoException;
import android.system.Os;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.FuseUnavailableMountException;
import com.android.internal.util.Preconditions;
+import com.android.server.NativeDaemonConnectorException;
import libcore.io.IoUtils;
import java.io.File;
import java.io.FileNotFoundException;
@@ -54,17 +56,17 @@ public class AppFuseBridge implements Runnable {
}
public ParcelFileDescriptor addBridge(MountScope mountScope)
- throws BridgeException {
+ throws FuseUnavailableMountException, NativeDaemonConnectorException {
try {
synchronized (this) {
Preconditions.checkArgument(mScopes.indexOfKey(mountScope.mountId) < 0);
if (mNativeLoop == 0) {
- throw new BridgeException("The thread has already been terminated");
+ throw new FuseUnavailableMountException(mountScope.mountId);
}
final int fd = native_add_bridge(
- mNativeLoop, mountScope.mountId, mountScope.deviceFd.detachFd());
+ mNativeLoop, mountScope.mountId, mountScope.open().detachFd());
if (fd == -1) {
- throw new BridgeException("Failed to invoke native_add_bridge");
+ throw new FuseUnavailableMountException(mountScope.mountId);
}
final ParcelFileDescriptor result = ParcelFileDescriptor.adoptFd(fd);
mScopes.put(mountScope.mountId, mountScope);
@@ -86,12 +88,12 @@ public class AppFuseBridge implements Runnable {
}
public ParcelFileDescriptor openFile(int pid, int mountId, int fileId, int mode)
- throws FileNotFoundException, SecurityException, InterruptedException {
+ throws FuseUnavailableMountException, InterruptedException {
final MountScope scope;
synchronized (this) {
scope = mScopes.get(mountId);
if (scope == null) {
- throw new FileNotFoundException("Cannot find mount point");
+ throw new FuseUnavailableMountException(mountId);
}
}
if (scope.pid != pid) {
@@ -99,17 +101,14 @@ public class AppFuseBridge implements Runnable {
}
final boolean result = scope.waitForMount();
if (result == false) {
- throw new FileNotFoundException("Mount failed");
+ throw new FuseUnavailableMountException(mountId);
}
try {
- if (Os.stat(scope.mountPoint.getPath()).st_ino != 1) {
- throw new FileNotFoundException("Could not find bridge mount point.");
- }
- } catch (ErrnoException e) {
- throw new FileNotFoundException(
- "Failed to stat mount point: " + scope.mountPoint.getParent());
+ return ParcelFileDescriptor.open(
+ new File(scope.mountPoint, String.valueOf(fileId)), mode);
+ } catch (FileNotFoundException error) {
+ throw new FuseUnavailableMountException(mountId);
}
- return ParcelFileDescriptor.open(new File(scope.mountPoint, String.valueOf(fileId)), mode);
}
// Used by com_android_server_storage_AppFuse.cpp.
@@ -130,20 +129,18 @@ public class AppFuseBridge implements Runnable {
}
}
- public static class MountScope implements AutoCloseable {
+ public static abstract class MountScope implements AutoCloseable {
public final int uid;
public final int pid;
public final int mountId;
- public final ParcelFileDescriptor deviceFd;
public final File mountPoint;
private final CountDownLatch mMounted = new CountDownLatch(1);
private boolean mMountResult = false;
- public MountScope(int uid, int pid, int mountId, ParcelFileDescriptor deviceFd) {
+ public MountScope(int uid, int pid, int mountId) {
this.uid = uid;
this.pid = pid;
this.mountId = mountId;
- this.deviceFd = deviceFd;
this.mountPoint = new File(String.format(APPFUSE_MOUNT_NAME_TEMPLATE, uid, mountId));
}
@@ -161,16 +158,7 @@ public class AppFuseBridge implements Runnable {
return mMountResult;
}
- @Override
- public void close() throws Exception {
- deviceFd.close();
- }
- }
-
- public static class BridgeException extends Exception {
- public BridgeException(String message) {
- super(message);
- }
+ public abstract ParcelFileDescriptor open() throws NativeDaemonConnectorException;
}
private native long native_new();
diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
index 41c5331e77b0..82dd9ace6a5e 100644
--- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
+++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
@@ -197,7 +197,7 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener {
.setQuota(CacheQuotaHint.QUOTA_NOT_SET)
.build());
} catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Unable to find package for quota calculation", e);
+ // This may happen if an app has a recorded usage, but has been uninstalled.
continue;
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index ebbb8b315d00..42f12eb23d39 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -16,6 +16,7 @@
package com.android.server.tv;
+import android.hardware.tv.input.V1_0.Constants;
import android.media.tv.TvInputHardwareInfo;
import android.media.tv.TvStreamConfig;
import android.os.Handler;
@@ -41,9 +42,10 @@ final class TvInputHal implements Handler.Callback {
public final static int ERROR_STALE_CONFIG = -2;
public final static int ERROR_UNKNOWN = -3;
- public static final int EVENT_DEVICE_AVAILABLE = 1;
- public static final int EVENT_DEVICE_UNAVAILABLE = 2;
- public static final int EVENT_STREAM_CONFIGURATION_CHANGED = 3;
+ public static final int EVENT_DEVICE_AVAILABLE = Constants.EVENT_DEVICE_AVAILABLE;
+ public static final int EVENT_DEVICE_UNAVAILABLE = Constants.EVENT_DEVICE_UNAVAILABLE;
+ public static final int EVENT_STREAM_CONFIGURATION_CHANGED =
+ Constants.EVENT_STREAM_CONFIGURATIONS_CHANGED;
public static final int EVENT_FIRST_FRAME_CAPTURED = 4;
public interface Callback {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 5abc4e4d2e56..f138add7ba09 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -222,11 +222,10 @@ final class AccessibilityController {
|| mWindowsForAccessibilityObserver != null);
}
- /** NOTE: This has to be called within a surface transaction. */
public void setForceShowMagnifiableBoundsLocked(boolean show) {
if (mDisplayMagnifier != null) {
mDisplayMagnifier.setForceShowMagnifiableBoundsLocked(show);
- mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked();
+ mDisplayMagnifier.showMagnificationBoundsIfNeeded();
}
}
@@ -440,6 +439,12 @@ final class AccessibilityController {
mMagnifedViewport.destroyWindow();
}
+ // Can be called outside of a surface transaction
+ public void showMagnificationBoundsIfNeeded() {
+ mHandler.obtainMessage(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)
+ .sendToTarget();
+ }
+
/** NOTE: This has to be called within a surface transaction. */
public void drawMagnifiedRegionBorderIfNeededLocked() {
mMagnifedViewport.drawWindowIfNeededLocked();
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index e60295de4876..4b4be40880ee 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -706,8 +706,8 @@ public class AppWindowContainerController
}
/** Calls directly into activity manager so window manager lock shouldn't held. */
- boolean keyDispatchingTimedOut(String reason) {
- return mListener != null && mListener.keyDispatchingTimedOut(reason);
+ boolean keyDispatchingTimedOut(String reason, int windowPid) {
+ return mListener != null && mListener.keyDispatchingTimedOut(reason, windowPid);
}
@Override
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerListener.java b/services/core/java/com/android/server/wm/AppWindowContainerListener.java
index 9d459cfccc09..26537f27bce8 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerListener.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerListener.java
@@ -33,6 +33,10 @@ public interface AppWindowContainerListener extends WindowContainerListener {
/**
* Called when the key dispatching to a window associated with the app window container
* timed-out.
+ *
+ * @param reason The reason for the key dispatching time out.
+ * @param windowPid The pid of the window key dispatching timed out on.
+ * @return True if input dispatching should be aborted.
*/
- boolean keyDispatchingTimedOut(String reason);
+ boolean keyDispatchingTimedOut(String reason, int windowPid);
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 72ae90d71a9e..1decf4e19e9f 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.StackId;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
@@ -1204,12 +1205,23 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
* in anyway.
*/
@Override
- int getOrientation() {
+ int getOrientation(int candidate) {
+ if (!fillsParent()) {
+ // Can't specify orientation if app doesn't fill parent.
+ return SCREEN_ORIENTATION_UNSET;
+ }
+
+ if (candidate == SCREEN_ORIENTATION_BEHIND) {
+ // Allow app to specify orientation regardless of its visibility state if the current
+ // candidate want us to use orientation behind. I.e. the visible app on-top of this one
+ // wants us to use the orientation of the app behind it.
+ return mOrientation;
+ }
+
// The {@link AppWindowToken} should only specify an orientation when it is not closing or
// going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
// an Activity in another task being started in the wrong orientation during the transition.
- if (fillsParent()
- && !(sendingToBottom || mService.mClosingApps.contains(this))
+ if (!(sendingToBottom || mService.mClosingApps.contains(this))
&& (isVisible() || mService.mOpeningApps.contains(this))) {
return mOrientation;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8f391a718269..aa8557490f25 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -175,6 +175,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
private boolean mTmpRecoveringMemory;
private boolean mUpdateImeTarget;
private boolean mTmpInitial;
+ private int mMaxUiWidth;
// Mapping from a token IBinder to a WindowToken object on this display.
private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
@@ -1559,6 +1560,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
+ /** Sets the maximum width the screen resolution can be */
+ void setMaxUiWidth(int width) {
+ if (DEBUG_DISPLAY) {
+ Slog.v(TAG_WM, "Setting max ui width:" + width + " on display:" + getDisplayId());
+ }
+
+ mMaxUiWidth = width;
+
+ // Update existing metrics.
+ updateBaseDisplayMetrics(mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
+ }
+
+ /** Update base (override) display metrics. */
+ void updateBaseDisplayMetrics(int baseWidth, int baseHeight, int baseDensity) {
+ mBaseDisplayWidth = baseWidth;
+ mBaseDisplayHeight = baseHeight;
+ mBaseDisplayDensity = baseDensity;
+
+ if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) {
+ mBaseDisplayHeight = (mMaxUiWidth * mBaseDisplayHeight) / mBaseDisplayWidth;
+ mBaseDisplayDensity = (mMaxUiWidth * mBaseDisplayDensity) / mBaseDisplayWidth;
+ mBaseDisplayWidth = mMaxUiWidth;
+
+ if (DEBUG_DISPLAY) {
+ Slog.v(TAG_WM, "Applying config restraints:" + mBaseDisplayWidth + "x"
+ + mBaseDisplayHeight + " at density:" + mBaseDisplayDensity
+ + " on display:" + getDisplayId());
+ }
+ }
+
+ mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
+ }
+
void getContentRect(Rect out) {
out.set(mContentRect);
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index d041c111a888..aae216e0d47c 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -258,7 +258,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
// Notify the activity manager about the timeout and let it decide whether
// to abort dispatching or keep waiting.
final AppWindowContainerController controller = appWindowToken.getController();
- final boolean abort = controller != null && controller.keyDispatchingTimedOut(reason);
+ final boolean abort = controller != null
+ && controller.keyDispatchingTimedOut(reason, windowState.mSession.mPid);
if (!abort) {
// The activity manager declined to abort dispatching.
// Wait a bit longer and timeout again later.
@@ -281,7 +282,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
return 0; // abort dispatching
}
- void addInputWindowHandle(final InputWindowHandle windowHandle) {
+ private void addInputWindowHandle(final InputWindowHandle windowHandle) {
if (mInputWindowHandles == null) {
mInputWindowHandles = new InputWindowHandle[16];
}
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 012480e0410d..3ce61f027b4c 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -195,7 +195,8 @@ class PinnedStackController {
* @return whether the given {@param aspectRatio} is valid.
*/
public boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
- return mMinAspectRatio <= aspectRatio && aspectRatio <= mMaxAspectRatio;
+ return Float.compare(mMinAspectRatio, aspectRatio) <= 0 &&
+ Float.compare(aspectRatio, mMaxAspectRatio) <= 0;
}
/**
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 68d0f2496d5a..b0e3e3221415 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -152,8 +152,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
}
WindowState computeFocusedWindow() {
- final int count = mChildren.size();
- for (int i = 0; i < count; i++) {
+ for (int i = mChildren.size() - 1; i >= 0; i--) {
final DisplayContent dc = mChildren.get(i);
final WindowState win = dc.findFocusedWindow();
if (win != null) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 2a02359cc529..84ba139ee5a9 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -516,14 +516,22 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
mOrientation = orientation;
}
+ int getOrientation() {
+ return getOrientation(mOrientation);
+ }
+
/**
* Returns the specified orientation for this window container or one of its children is there
* is one set, or {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSET} if no
* specification is set.
* NOTE: {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} is a
* specification...
+ *
+ * @param candidate The current orientation candidate that will be returned if we don't find a
+ * better match.
+ * @return The orientation as specified by this branch or the window hierarchy.
*/
- int getOrientation() {
+ int getOrientation(int candidate) {
if (!fillsParent()) {
// Ignore containers that don't completely fill their parents.
return SCREEN_ORIENTATION_UNSET;
@@ -537,12 +545,14 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
&& mOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
return mOrientation;
}
- int candidate = mOrientation;
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer wc = mChildren.get(i);
- final int orientation = wc.getOrientation();
+ // TODO: Maybe mOrientation should default to SCREEN_ORIENTATION_UNSET vs.
+ // SCREEN_ORIENTATION_UNSPECIFIED?
+ final int orientation = wc.getOrientation(candidate == SCREEN_ORIENTATION_BEHIND
+ ? SCREEN_ORIENTATION_BEHIND : SCREEN_ORIENTATION_UNSET);
if (orientation == SCREEN_ORIENTATION_BEHIND) {
// container wants us to use the orientation of the container behind it. See if we
// can find one. Else return SCREEN_ORIENTATION_BEHIND so the caller can choose to
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fa9c2a7edae2..0dc74d72635b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -385,6 +385,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mAllowBootMessages;
final boolean mLimitedAlphaCompositing;
+ final int mMaxUiWidth;
final WindowManagerPolicy mPolicy;
@@ -949,6 +950,8 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.integer.config_drawLockTimeoutMillis);
mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
+ mMaxUiWidth = context.getResources().getInteger(
+ com.android.internal.R.integer.config_maxUiWidth);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplaySettings = new DisplaySettings();
@@ -4572,6 +4575,9 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ if (mMaxUiWidth > 0) {
+ displayContent.setMaxUiWidth(mMaxUiWidth);
+ }
readForcedDisplayPropertiesLocked(displayContent);
mDisplayReady = true;
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 826fb455b6e2..1eedc28fbad4 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -591,6 +591,17 @@ class WindowStateAnimator {
}
}
+ private int getLayerStack() {
+ return mWin.getDisplayContent().getDisplay().getLayerStack();
+ }
+
+ void updateLayerStackInTransaction() {
+ if (mSurfaceController != null) {
+ mSurfaceController.setLayerStackInTransaction(
+ getLayerStack());
+ }
+ }
+
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
final WindowState w = mWin;
if (w.restoreSavedSurface()) {
@@ -703,8 +714,7 @@ class WindowStateAnimator {
}
// Start a new transaction and apply position & offset.
- final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
- mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack, mAnimLayer);
+ mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, getLayerStack(), mAnimLayer);
mLastHidden = true;
if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
@@ -1435,7 +1445,6 @@ class WindowStateAnimator {
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
w.applyDimLayerIfNeeded();
}
-
}
void prepareSurfaceLocked(final boolean recoveringMemory) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index b08bb70ca0b9..fb40a65005f0 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -276,6 +276,12 @@ class WindowSurfaceController {
}
}
+ void setLayerStackInTransaction(int layerStack) {
+ if (mSurfaceControl != null) {
+ mSurfaceControl.setLayerStack(layerStack);
+ }
+ }
+
void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
if (surfaceMoved) {
@@ -357,7 +363,8 @@ class WindowSurfaceController {
return false;
}
- boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy,
+ boolean prepareToShowInTransaction(float alpha, int layer,
+ float dsdx, float dtdx, float dsdy,
float dtdy, boolean recoveringMemory) {
if (mSurfaceControl != null) {
try {
@@ -371,7 +378,6 @@ class WindowSurfaceController {
mLastDtdy = dtdy;
mSurfaceControl.setMatrix(
dsdx, dtdx, dsdy, dtdy);
-
} catch (RuntimeException e) {
Slog.w(TAG, "Error updating surface in " + title, e);
if (!recoveringMemory) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index fab59d6c8f08..e3033c9c01a8 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -30,6 +30,7 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import android.os.Debug;
import android.os.IBinder;
import android.util.Slog;
+import android.view.SurfaceControl;
import java.io.PrintWriter;
@@ -245,6 +246,18 @@ class WindowToken extends WindowContainer<WindowState> {
void onDisplayChanged(DisplayContent dc) {
dc.reParentWindowToken(this);
mDisplayContent = dc;
+
+ // TODO(b/36740756): One day this should perhaps be hooked
+ // up with goodToGo, so we don't move a window
+ // to another display before the window behind
+ // it is ready.
+ SurfaceControl.openTransaction();
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final WindowState win = mChildren.get(i);
+ win.mWinAnimator.updateLayerStackInTransaction();
+ }
+ SurfaceControl.closeTransaction();
+
super.onDisplayChanged(dc);
}
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index ec36df1d9a12..57bb9fedc135 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -57,6 +57,8 @@ namespace android
static bool wakeup_init = false;
static sem_t wakeup_sem;
extern sp<IPower> gPowerHal;
+extern std::mutex gPowerHalMutex;
+extern bool getPowerHal();
static void wakeup_callback(bool success)
{
@@ -191,41 +193,26 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o
return -1;
}
- if (gPowerHal == nullptr) {
- ALOGE("gPowerHal not loaded");
- return -1;
- }
+ {
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (!getPowerHal()) {
+ ALOGE("Power Hal not loaded");
+ return -1;
+ }
- gPowerHal->getPlatformLowPowerStats(
- [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
- Status status) {
- if (status != Status::SUCCESS)
- return;
- for (size_t i = 0; i < states.size(); i++) {
- int added;
- const PowerStatePlatformSleepState& state = states[i];
-
- added = snprintf(offset, remaining,
- "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
- i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
- state.totalTransitions);
- if (added < 0) {
- break;
- }
- if (added > remaining) {
- added = remaining;
- }
- offset += added;
- remaining -= added;
- total_added += added;
+ Return<void> ret = gPowerHal->getPlatformLowPowerStats(
+ [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
+ Status status) {
+ if (status != Status::SUCCESS)
+ return;
+ for (size_t i = 0; i < states.size(); i++) {
+ int added;
+ const PowerStatePlatformSleepState& state = states[i];
- for (size_t j = 0; j < state.voters.size(); j++) {
- const PowerStateVoter& voter = state.voters[j];
added = snprintf(offset, remaining,
- "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
- j + 1, voter.name.c_str(),
- voter.totalTimeInMsecVotedForSinceBoot,
- voter.totalNumberOfTimesVotedSinceBoot);
+ "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+ i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
+ state.totalTransitions);
if (added < 0) {
break;
}
@@ -235,18 +222,42 @@ static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject o
offset += added;
remaining -= added;
total_added += added;
- }
- if (remaining <= 0) {
- /* rewrite NULL character*/
- offset--;
- total_added--;
- ALOGE("PowerHal: buffer not enough");
- break;
+ for (size_t j = 0; j < state.voters.size(); j++) {
+ const PowerStateVoter& voter = state.voters[j];
+ added = snprintf(offset, remaining,
+ "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+ j + 1, voter.name.c_str(),
+ voter.totalTimeInMsecVotedForSinceBoot,
+ voter.totalNumberOfTimesVotedSinceBoot);
+ if (added < 0) {
+ break;
+ }
+ if (added > remaining) {
+ added = remaining;
+ }
+ offset += added;
+ remaining -= added;
+ total_added += added;
+ }
+
+ if (remaining <= 0) {
+ /* rewrite NULL character*/
+ offset--;
+ total_added--;
+ ALOGE("PowerHal: buffer not enough");
+ break;
+ }
}
}
+ );
+
+ if (!ret.isOk()) {
+ ALOGE("getPlatformLowPowerStats() failed: power HAL service not available");
+ gPowerHal = nullptr;
+ return -1;
}
- );
+ }
*offset = 0;
total_added += 1;
return total_added;
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index fab309bfb148..1bdcd7aa9bd6 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -43,7 +43,7 @@ using android::hardware::Void;
using android::hardware::power::V1_0::IPower;
using android::hardware::power::V1_0::PowerHint;
using android::hardware::power::V1_0::Feature;
-using android::hardware::hidl_vec;
+using android::String8;
namespace android {
@@ -56,7 +56,8 @@ static struct {
// ----------------------------------------------------------------------------
static jobject gPowerManagerServiceObj;
-sp<IPower> gPowerHal;
+sp<IPower> gPowerHal = nullptr;
+std::mutex gPowerHalMutex;
static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
// Throttling interval for user activity calls.
@@ -74,11 +75,37 @@ static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa
return false;
}
+// Check validity of current handle to the power HAL service, and call getService() if necessary.
+// The caller must be holding gPowerHalMutex.
+bool getPowerHal() {
+ if (gPowerHal == nullptr) {
+ gPowerHal = IPower::getService();
+ if (gPowerHal != nullptr) {
+ ALOGI("Loaded power HAL service");
+ } else {
+ ALOGI("Couldn't load power HAL service");
+ }
+ }
+ return gPowerHal != nullptr;
+}
+
+// Check if a call to a power HAL function failed; if so, log the failure and invalidate the
+// current handle to the power HAL service. The caller must be holding gPowerHalMutex.
+static void processReturn(const Return<void> &ret, const char* functionName) {
+ if (!ret.isOk()) {
+ ALOGE("%s() failed: power HAL service not available.", functionName);
+ gPowerHal = nullptr;
+ }
+}
+
void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
// Tell the power HAL when user activity occurs.
- if (gPowerHal != nullptr) {
- gPowerHal->powerHint(PowerHint::INTERACTION, 0);
+ gPowerHalMutex.lock();
+ if (getPowerHal()) {
+ Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0);
+ processReturn(ret, "powerHint");
}
+ gPowerHalMutex.unlock();
if (gPowerManagerServiceObj) {
// Throttle calls into user activity by event type.
@@ -106,14 +133,13 @@ void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t
}
// ----------------------------------------------------------------------------
-//TODO(b/31632518)
+
static void nativeInit(JNIEnv* env, jobject obj) {
gPowerManagerServiceObj = env->NewGlobalRef(obj);
- gPowerHal = IPower::getService();
- if (gPowerHal == nullptr) {
- ALOGE("Couldn't load PowerHAL module");
- }
+ gPowerHalMutex.lock();
+ getPowerHal();
+ gPowerHalMutex.unlock();
}
static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
@@ -127,14 +153,12 @@ static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring
}
static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
- if (gPowerHal != nullptr) {
- if (enable) {
- ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
- gPowerHal->setInteractive(true);
- } else {
- ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
- gPowerHal->setInteractive(false);
- }
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (getPowerHal()) {
+ String8 err("Excessive delay in setInteractive(%s) while turning screen %s");
+ ALOGD_IF_SLOW(20, String8::format(err, enable ? "true" : "false", enable ? "on" : "off"));
+ Return<void> ret = gPowerHal->setInteractive(enable);
+ processReturn(ret, "setInteractive");
}
}
@@ -149,20 +173,18 @@ static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean
}
static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) {
- if (gPowerHal != nullptr) {
- if(data)
- gPowerHal->powerHint((PowerHint)hintId, data);
- else {
- gPowerHal->powerHint((PowerHint)hintId, 0);
- }
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (getPowerHal()) {
+ Return<void> ret = gPowerHal->powerHint((PowerHint)hintId, data);
+ processReturn(ret, "powerHint");
}
}
static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
- int data_param = data;
-
- if (gPowerHal != nullptr) {
- gPowerHal->setFeature((Feature)featureId, data_param ? true : false);
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (getPowerHal()) {
+ Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data));
+ processReturn(ret, "setFeature");
}
}
@@ -217,7 +239,6 @@ int register_android_server_PowerManagerService(JNIEnv* env) {
gLastEventTime[i] = LLONG_MIN;
}
gPowerManagerServiceObj = NULL;
- gPowerHal = NULL;
return 0;
}
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index b4333508a84a..78c0fa7d334a 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -577,7 +577,6 @@ JTvInputHal::TvInputCallback::TvInputCallback(JTvInputHal* hal) {
}
Return<void> JTvInputHal::TvInputCallback::notify(const TvInputEvent& event) {
- // TODO(b/32200867): Ensure the event type values are in sync with the framework code.
mHal->mLooper->sendMessage(new NotifyHandler(mHal, event), static_cast<int>(event.type));
return Void();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 9b4de043a647..70c7e586d3fe 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -26,6 +26,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
+import android.util.LongSparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -44,12 +45,21 @@ final class NetworkLoggingHandler extends Handler {
// If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc
private static final int MAX_EVENTS_PER_BATCH = 1200;
- private static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90);
- private static final long BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS =
- TimeUnit.MINUTES.toMillis(30);
+
+ /**
+ * Maximum number of batches to store in memory. If more batches are generated and the DO
+ * doesn't fetch them, we will discard the oldest one.
+ */
+ private static final int MAX_BATCHES = 5;
+
+ private static final long BATCH_FINALIZATION_TIMEOUT_MS = 90 * 60 * 1000; // 1.5h
+ private static final long BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS = 30 * 60 * 1000; // 30m
private static final String NETWORK_LOGGING_TIMEOUT_ALARM_TAG = "NetworkLogging.batchTimeout";
+ /** Delay after which older batches get discarded after a retrieval. */
+ private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
+
private final DevicePolicyManagerService mDpm;
private final AlarmManager mAlarmManager;
@@ -66,22 +76,27 @@ final class NetworkLoggingHandler extends Handler {
static final int LOG_NETWORK_EVENT_MSG = 1;
- // threadsafe as it's Handler's thread confined
+ /** Network events accumulated so far to be finalized into a batch at some point. */
@GuardedBy("this")
- private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<NetworkEvent>();
+ private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<>();
+ /**
+ * Up to {@code MAX_BATCHES} finalized batches of logs ready to be retrieved by the DO. Already
+ * retrieved batches are discarded after {@code RETRIEVED_BATCH_DISCARD_DELAY_MS}.
+ */
@GuardedBy("this")
- private ArrayList<NetworkEvent> mFullBatch;
+ private final LongSparseArray<ArrayList<NetworkEvent>> mBatches =
+ new LongSparseArray<>(MAX_BATCHES);
@GuardedBy("this")
private boolean mPaused = false;
// each full batch is represented by its token, which the DPC has to provide back to retrieve it
@GuardedBy("this")
- private long mCurrentFullBatchToken;
+ private long mCurrentBatchToken;
@GuardedBy("this")
- private long mLastRetrievedFullBatchToken;
+ private long mLastRetrievedBatchToken;
NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
super(looper);
@@ -93,7 +108,7 @@ final class NetworkLoggingHandler extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case LOG_NETWORK_EVENT_MSG: {
- NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
+ final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
if (networkEvent != null) {
synchronized (NetworkLoggingHandler.this) {
mNetworkEvents.add(networkEvent);
@@ -113,6 +128,8 @@ final class NetworkLoggingHandler extends Handler {
void scheduleBatchFinalization() {
final long when = SystemClock.elapsedRealtime() + BATCH_FINALIZATION_TIMEOUT_MS;
+ // We use alarm manager and not just postDelayed here to ensure the batch gets finalized
+ // even if the device goes to sleep.
mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
mBatchTimeoutAlarmListener, this);
@@ -131,62 +148,80 @@ final class NetworkLoggingHandler extends Handler {
return;
}
- Log.d(TAG, "Resumed network logging. Current batch="
- + mCurrentFullBatchToken + ", LastRetrievedBatch=" + mLastRetrievedFullBatchToken);
+ Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+ + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
mPaused = false;
- // If there is a full batch ready that the device owner hasn't been notified about, do it
- // now.
- if (mFullBatch != null && mFullBatch.size() > 0
- && mLastRetrievedFullBatchToken != mCurrentFullBatchToken) {
+ // If there is a batch ready that the device owner hasn't been notified about, do it now.
+ if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
scheduleBatchFinalization();
notifyDeviceOwnerLocked();
}
}
synchronized void discardLogs() {
- mFullBatch = null;
- mNetworkEvents = new ArrayList<NetworkEvent>();
+ mBatches.clear();
+ mNetworkEvents = new ArrayList<>();
Log.d(TAG, "Discarded all network logs");
}
@GuardedBy("this")
private void finalizeBatchAndNotifyDeviceOwnerLocked() {
if (mNetworkEvents.size() > 0) {
- // finalize the batch and start a new one from scratch
- mFullBatch = mNetworkEvents;
- mCurrentFullBatchToken++;
- mNetworkEvents = new ArrayList<NetworkEvent>();
+ // Finalize the batch and start a new one from scratch.
+ if (mBatches.size() >= MAX_BATCHES) {
+ // Remove the oldest batch if we hit the limit.
+ mBatches.removeAt(0);
+ }
+ mCurrentBatchToken++;
+ mBatches.append(mCurrentBatchToken, mNetworkEvents);
+ mNetworkEvents = new ArrayList<>();
if (!mPaused) {
notifyDeviceOwnerLocked();
}
} else {
- // don't notify the DO, since there are no events; DPC can still retrieve
+ // Don't notify the DO, since there are no events; DPC can still retrieve
// the last full batch if not paused.
Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
- + " the DPC, the batchToken of last available batch: "
- + mCurrentFullBatchToken);
+ + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
}
- // regardless of whether the batch was non-empty schedule a new finalization after timeout
+ // Regardless of whether the batch was non-empty schedule a new finalization after timeout.
scheduleBatchFinalization();
}
+ /** Sends a notification to the DO. Should only be called when there is a batch available. */
@GuardedBy("this")
private void notifyDeviceOwnerLocked() {
- Bundle extras = new Bundle();
- extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken);
- extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size());
+ final Bundle extras = new Bundle();
+ final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
+ extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
+ extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
- + mCurrentFullBatchToken);
+ + mCurrentBatchToken);
mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
}
- synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) {
- if (batchToken != mCurrentFullBatchToken) {
+ synchronized List<NetworkEvent> retrieveFullLogBatch(final long batchToken) {
+ final int index = mBatches.indexOfKey(batchToken);
+ if (index < 0) {
+ // Invalid token or batch has already been discarded.
return null;
}
- mLastRetrievedFullBatchToken = mCurrentFullBatchToken;
- return mFullBatch;
+
+ // Schedule this and older batches to be discarded after a delay to lessen memory load
+ // without interfering with the admin's ability to collect logs out-of-order.
+ // It isn't critical and we allow it to be delayed further if the phone sleeps, so we don't
+ // use the alarm manager here.
+ postDelayed(() -> {
+ synchronized(this) {
+ while (mBatches.size() > 0 && mBatches.keyAt(0) <= batchToken) {
+ mBatches.removeAt(0);
+ }
+ }
+ }, RETRIEVED_BATCH_DISCARD_DELAY_MS);
+
+ mLastRetrievedBatchToken = batchToken;
+ return mBatches.valueAt(index);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f0732dd56f7a..3f197b7f3927 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -317,7 +317,7 @@ public final class SystemServer {
// In case the runtime switched since last boot (such as when
// the old runtime was removed in an OTA), set the system
- // property so that it is in sync. We can't do this in
+ // property so that it is in sync. We can | xq oqi't do this in
// libnativehelper's JniInvocation::Init code where we already
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
@@ -665,6 +665,7 @@ public final class SystemServer {
VibratorService vibrator = null;
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
+ IpSecService ipSecService = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
@@ -1012,6 +1013,15 @@ public final class SystemServer {
reportWtf("starting NetworkManagement Service", e);
}
traceEnd();
+
+ traceBeginAndSlog("StartIpSecService");
+ try {
+ ipSecService = IpSecService.create(context);
+ ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
+ } catch (Throwable e) {
+ reportWtf("starting IpSec Service", e);
+ }
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
if (!disableNonCoreServices) {
@@ -1631,6 +1641,7 @@ public final class SystemServer {
final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
final MediaRouterService mediaRouterF = mediaRouter;
final MmsServiceBroker mmsServiceF = mmsService;
+ final IpSecService ipSecServiceF = ipSecService;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
@@ -1688,6 +1699,13 @@ public final class SystemServer {
} catch (Throwable e) {
reportWtf("making Network Managment Service ready", e);
}
+ Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeIpSecServiceReady");
+ try {
+ if (ipSecServiceF != null) ipSecServiceF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making IpSec Service ready", e);
+ }
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
CountDownLatch networkPolicyInitReadySignal = null;
if (networkPolicyF != null) {
networkPolicyInitReadySignal = networkPolicyF
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 7b4fa8798885..590bce186430 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -608,7 +608,7 @@ public class IpManager extends StateMachine {
}
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- if (args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
+ if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
// Execute confirmConfiguration() and take no further action.
confirmConfiguration();
return;
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
index 9356dacc29f8..7790698d02e9 100644
--- a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -20,6 +20,7 @@ package com.android.server.print;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.Manifest;
+import android.annotation.CheckResult;
import android.annotation.Nullable;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
@@ -36,8 +37,11 @@ import android.content.pm.PackageManager;
import android.net.NetworkPolicyManager;
import android.os.Binder;
import android.os.Environment;
+import android.os.Handler;
import android.os.IBinder;
import android.os.IDeviceIdleController;
+import android.os.IInterface;
+import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -68,11 +72,13 @@ import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
//TODO move to own package!
-//TODO un/linkToDeath & onBinderDied - unbind
//TODO onStop schedule unbind in 5 seconds
-//TODO Prune association on app uninstall
+//TODO make sure APIs are only callable from currently focused app
+//TODO schedule stopScan on activity destroy(except if configuration change)
+//TODO on associate called again after configuration change -> replace old callback with new
+//TODO avoid leaking calling activity in IFindDeviceCallback (see PrintManager#print for example)
/** @hide */
-public class CompanionDeviceManagerService extends SystemService {
+public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient {
private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
@@ -90,6 +96,8 @@ public class CompanionDeviceManagerService extends SystemService {
private final CompanionDeviceManagerImpl mImpl;
private final ConcurrentMap<Integer, AtomicFile> mUidToStorage = new ConcurrentHashMap<>();
private IDeviceIdleController mIdleController;
+ private IFindDeviceCallback mFindDeviceCallback;
+ private ServiceConnection mServiceConnection;
public CompanionDeviceManagerService(Context context) {
super(context);
@@ -125,7 +133,51 @@ public class CompanionDeviceManagerService extends SystemService {
publishBinderService(Context.COMPANION_DEVICE_SERVICE, mImpl);
}
+ @Override
+ public void binderDied() {
+ Handler.getMain().post(this::handleBinderDied);
+ }
+
+ private void handleBinderDied() {
+ mServiceConnection = unbind(mServiceConnection);
+ mFindDeviceCallback = unlinkToDeath(mFindDeviceCallback, this, 0);
+ }
+
+ /**
+ * Usage: {@code a = unlinkToDeath(a, deathRecipient, flags); }
+ */
+ @Nullable
+ @CheckResult
+ private static <T extends IInterface> T unlinkToDeath(T iinterface,
+ IBinder.DeathRecipient deathRecipient, int flags) {
+ if (iinterface != null) {
+ iinterface.asBinder().unlinkToDeath(deathRecipient, flags);
+ }
+ return null;
+ }
+
+ @Nullable
+ @CheckResult
+ private ServiceConnection unbind(@Nullable ServiceConnection conn) {
+ if (conn != null) {
+ getContext().unbindService(conn);
+ }
+ return null;
+ }
+
class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub {
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ try {
+ return super.onTransact(code, data, reply, flags);
+ } catch (Throwable e) {
+ Slog.e(LOG_TAG, "Error during IPC", e);
+ throw ExceptionUtils.propagate(e, RemoteException.class);
+ }
+ }
+
@Override
public void associate(
AssociationRequest request,
@@ -135,14 +187,14 @@ public class CompanionDeviceManagerService extends SystemService {
Slog.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+ ", callingPackage = " + callingPackage + ")");
}
- checkNotNull(request);
- checkNotNull(callback);
+ checkNotNull(request, "Request cannot be null");
+ checkNotNull(callback, "Callback cannot be null");
final long callingIdentity = Binder.clearCallingIdentity();
try {
//TODO bindServiceAsUser
getContext().bindService(
new Intent().setComponent(SERVICE_TO_BIND_TO),
- getServiceConnection(request, callback, callingPackage),
+ createServiceConnection(request, callback, callingPackage),
Context.BIND_AUTO_CREATE);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
@@ -168,11 +220,11 @@ public class CompanionDeviceManagerService extends SystemService {
return UserHandle.getUserId(Binder.getCallingUid());
}
- private ServiceConnection getServiceConnection(
+ private ServiceConnection createServiceConnection(
final AssociationRequest request,
final IFindDeviceCallback findDeviceCallback,
final String callingPackage) {
- return new ServiceConnection() {
+ mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) {
@@ -180,6 +232,14 @@ public class CompanionDeviceManagerService extends SystemService {
"onServiceConnected(name = " + name + ", service = "
+ service + ")");
}
+ mFindDeviceCallback = findDeviceCallback;
+ try {
+ mFindDeviceCallback.asBinder().linkToDeath(
+ CompanionDeviceManagerService.this, 0);
+ } catch (RemoteException e) {
+ handleBinderDied();
+ return;
+ }
try {
ICompanionDeviceDiscoveryService.Stub
.asInterface(service)
@@ -198,6 +258,7 @@ public class CompanionDeviceManagerService extends SystemService {
if (DEBUG) Slog.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
}
};
+ return mServiceConnection;
}
private ICompanionDeviceDiscoveryServiceCallback.Stub getServiceCallback() {
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 2a8f4a34f158..bb4507d8386a 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -52,6 +52,7 @@ LOCAL_JNI_SHARED_LIBRARIES := \
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_JACK_FLAGS := --multi-dex native
+LOCAL_DX_FLAGS := --multi-dex
LOCAL_STATIC_JAVA_LIBRARIES += ub-uiautomator
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 29c6f89e5fa0..3671e4b86158 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -19,6 +19,7 @@ package com.android.server;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
+import static android.net.NetworkPolicy.SNOOZE_NEVER;
import static android.net.NetworkPolicy.WARNING_DISABLED;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.POLICY_NONE;
@@ -26,8 +27,15 @@ import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
import static android.net.NetworkPolicyManager.computeNextCycleBoundary;
import static android.net.NetworkPolicyManager.uidPoliciesToString;
+import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
+import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
+import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
+import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
+import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
+import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.Time.TIMEZONE_UTC;
@@ -94,18 +102,24 @@ import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.os.Binder;
import android.os.INetworkManagementService;
+import android.os.PersistableBundle;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.Time;
import android.util.Log;
import android.util.TrustedTime;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
import com.android.server.net.NetworkPolicyManagerInternal;
@@ -143,6 +157,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -200,20 +215,34 @@ public class NetworkPolicyManagerServiceTest {
private @Mock INotificationManager mNotifManager;
private @Mock PackageManager mPackageManager;
private @Mock IPackageManager mIpm;
+ private @Mock SubscriptionManager mSubscriptionManager;
+ private @Mock CarrierConfigManager mCarrierConfigManager;
+ private @Mock TelephonyManager mTelephonyManager;
private static ActivityManagerInternal mActivityManagerInternal;
private IUidObserver mUidObserver;
private INetworkManagementEventObserver mNetworkObserver;
- private PowerManagerInternal mPowerManagerInternal;
private NetworkPolicyListenerAnswer mPolicyListener;
private NetworkPolicyManagerService mService;
+ /**
+ * In some of the tests while initializing NetworkPolicyManagerService,
+ * ACTION_RESTRICT_BACKGROUND_CHANGED is broadcasted. This is for capturing that broadcast.
+ */
+ private FutureIntent mFutureIntent;
+
private long mStartTime;
private long mElapsedRealtime;
private static final int USER_ID = 0;
+ private static final int FAKE_SUB_ID = 3737373;
+ private static final String FAKE_SUBSCRIBER_ID = "FAKE_SUB_ID";
+ private static final int DEFAULT_CYCLE_DAY = 1;
+ private static final int INVALID_CARRIER_CONFIG_VALUE = -9999;
+ private long mDefaultWarningBytes; // filled in with the actual default before tests are run
+ private long mDefaultLimitBytes; // filled in with the actual default before tests are run
private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4;
private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8;
@@ -233,12 +262,13 @@ public class NetworkPolicyManagerServiceTest {
public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
- @BeforeClass
- public static void registerLocalServices() {
+ private void registerLocalServices() {
addLocalServiceMock(DeviceIdleController.LocalService.class);
+
final UsageStatsManagerInternal usageStats =
addLocalServiceMock(UsageStatsManagerInternal.class);
when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
+
mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class);
final PowerSaveState state = new PowerSaveState.Builder()
@@ -255,7 +285,9 @@ public class NetworkPolicyManagerServiceTest {
setCurrentTimeMillis(TEST_START);
- // intercept various broadcasts, and pretend that uids have packages
+ registerLocalServices();
+ // Intercept various broadcasts, and pretend that uids have packages.
+ // Also return mock service instances for a few critical services.
mServiceContext = new BroadcastInterceptingContext(context) {
@Override
public PackageManager getPackageManager() {
@@ -266,6 +298,20 @@ public class NetworkPolicyManagerServiceTest {
public void startActivity(Intent intent) {
// ignored
}
+
+ @Override
+ public Object getSystemService(String name) {
+ switch (name) {
+ case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
+ return mSubscriptionManager;
+ case Context.CARRIER_CONFIG_SERVICE:
+ return mCarrierConfigManager;
+ case Context.TELEPHONY_SERVICE:
+ return mTelephonyManager;
+ default:
+ return super.getSystemService(name);
+ }
+ }
};
setNetpolicyXml(context);
@@ -281,6 +327,7 @@ public class NetworkPolicyManagerServiceTest {
}).when(mActivityManager).registerUidObserver(any(), anyInt(),
eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
+ mFutureIntent = newRestrictBackgroundChangedFuture();
mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService,
mNetworkManager, mIpm, mTime, mPolicyDir, true);
mService.bindConnectivityManager(mConnManager);
@@ -321,6 +368,10 @@ public class NetworkPolicyManagerServiceTest {
ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
verify(mNetworkManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue();
+
+ NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, "");
+ mDefaultWarningBytes = defaultPolicy.warningBytes;
+ mDefaultLimitBytes = defaultPolicy.limitBytes;
}
@After
@@ -334,6 +385,12 @@ public class NetworkPolicyManagerServiceTest {
public void unregisterLocalServices() throws Exception {
// Registered by NetworkPolicyManagerService's constructor.
LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
+
+ // Added in registerLocalServices()
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ LocalServices.removeServiceForTest(PowerManagerInternal.class);
+ LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class);
+ LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
}
@Test
@@ -348,6 +405,7 @@ public class NetworkPolicyManagerServiceTest {
@NetPolicyXml("restrict-background-on.xml")
public void testTurnRestrictBackgroundOff() throws Exception {
assertRestrictBackgroundOn(); // Sanity check.
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
setRestrictBackground(false);
assertRestrictBackgroundChangedReceived(futureIntent, null);
@@ -360,6 +418,7 @@ public class NetworkPolicyManagerServiceTest {
@NetPolicyXml("restrict-background-on.xml")
public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
assertRestrictBackgroundOn(); // Sanity check.
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
addRestrictBackgroundWhitelist(true);
}
@@ -400,6 +459,7 @@ public class NetworkPolicyManagerServiceTest {
@NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
assertRestrictBackgroundOn(); // Sanity check.
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
removeRestrictBackgroundWhitelist(true);
}
@@ -519,6 +579,7 @@ public class NetworkPolicyManagerServiceTest {
@NetPolicyXml("restrict-background-on.xml")
public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
assertRestrictBackgroundOn(); // Sanity check.
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
addRestrictBackgroundBlacklist(false);
}
@@ -555,6 +616,7 @@ public class NetworkPolicyManagerServiceTest {
@NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
assertRestrictBackgroundOn(); // Sanity check.
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
removeRestrictBackgroundBlacklist(false);
}
@@ -590,6 +652,7 @@ public class NetworkPolicyManagerServiceTest {
public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
// Sanity checks.
assertRestrictBackgroundOn();
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
@@ -602,6 +665,7 @@ public class NetworkPolicyManagerServiceTest {
public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
// Sanity checks.
assertRestrictBackgroundOn();
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
assertWhitelistUids(UID_A);
final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
@@ -614,6 +678,7 @@ public class NetworkPolicyManagerServiceTest {
public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception {
// Sanity checks.
assertRestrictBackgroundOn();
+ assertRestrictBackgroundChangedReceived(mFutureIntent, null);
assertWhitelistUids(UID_A);
final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
@@ -696,19 +761,19 @@ public class NetworkPolicyManagerServiceTest {
@Test
public void testUidForeground() throws Exception {
// push all uids into background
- mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
- mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
+ callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
+ callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
assertFalse(mService.isUidForeground(UID_A));
assertFalse(mService.isUidForeground(UID_B));
// push one of the uids into foreground
- mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
+ callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
assertTrue(mService.isUidForeground(UID_A));
assertFalse(mService.isUidForeground(UID_B));
// and swap another uid into foreground
- mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
- mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
+ callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
+ callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
assertFalse(mService.isUidForeground(UID_A));
assertTrue(mService.isUidForeground(UID_B));
}
@@ -1066,8 +1131,7 @@ public class NetworkPolicyManagerServiceTest {
@Test
public void testOnUidStateChanged_notifyAMS() throws Exception {
final long procStateSeq = 222;
- mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE,
- procStateSeq);
+ callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq);
verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@@ -1079,6 +1143,16 @@ public class NetworkPolicyManagerServiceTest {
outputStream.toString().trim());
}
+ private void callOnUidStateChanged(int uid, int procState, long procStateSeq)
+ throws Exception {
+ mUidObserver.onUidStateChanged(uid, procState, procStateSeq);
+ final CountDownLatch latch = new CountDownLatch(1);
+ mService.mUidEventHandler.post(() -> {
+ latch.countDown();
+ });
+ latch.await(2, TimeUnit.SECONDS);
+ }
+
@Test
public void testProcStateHistory() {
// Verify dump works correctly with no elements added.
@@ -1132,6 +1206,269 @@ public class NetworkPolicyManagerServiceTest {
}
}
+ private void assertCycleDayAsExpected(PersistableBundle config, int carrierCycleDay,
+ boolean expectValid) {
+ config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, carrierCycleDay);
+ int actualCycleDay = mService.getCycleDayFromCarrierConfig(config,
+ INVALID_CARRIER_CONFIG_VALUE);
+ if (expectValid) {
+ assertEquals(carrierCycleDay, actualCycleDay);
+ } else {
+ // INVALID_CARRIER_CONFIG_VALUE is returned for invalid values
+ assertEquals(INVALID_CARRIER_CONFIG_VALUE, actualCycleDay);
+ }
+ }
+
+ @Test
+ public void testGetCycleDayFromCarrierConfig() {
+ PersistableBundle config = CarrierConfigManager.getDefaultConfig();
+ final Calendar cal = Calendar.getInstance();
+ int actualCycleDay;
+
+ config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ actualCycleDay = mService.getCycleDayFromCarrierConfig(config, DEFAULT_CYCLE_DAY);
+ assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
+
+ // null config returns a default value
+ actualCycleDay = mService.getCycleDayFromCarrierConfig(null, DEFAULT_CYCLE_DAY);
+ assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
+
+ // Sane, non-default values
+ assertCycleDayAsExpected(config, 1, true);
+ assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH), true);
+ assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH), true);
+
+ // Invalid values
+ assertCycleDayAsExpected(config, 0, false);
+ assertCycleDayAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, false);
+ assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH) + 1, false);
+ assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH) - 5, false);
+ }
+
+ private void assertWarningBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
+ long expected) {
+ config.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, carrierWarningBytes);
+ long actualWarning = mService.getWarningBytesFromCarrierConfig(config,
+ INVALID_CARRIER_CONFIG_VALUE);
+ assertEquals(expected, actualWarning);
+ }
+
+ @Test
+ public void testGetWarningBytesFromCarrierConfig() {
+ PersistableBundle config = CarrierConfigManager.getDefaultConfig();
+ long actualWarningBytes;
+
+ assertWarningBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
+ mDefaultWarningBytes);
+ assertWarningBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, WARNING_DISABLED);
+ assertWarningBytesAsExpected(config, 0, 0);
+ // not a valid value
+ assertWarningBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
+
+ // null config returns a default value
+ actualWarningBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultWarningBytes);
+ assertEquals(mDefaultWarningBytes, actualWarningBytes);
+ }
+
+ private void assertLimitBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
+ long expected) {
+ config.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, carrierWarningBytes);
+ long actualWarning = mService.getLimitBytesFromCarrierConfig(config,
+ INVALID_CARRIER_CONFIG_VALUE);
+ assertEquals(expected, actualWarning);
+ }
+
+ @Test
+ public void testGetLimitBytesFromCarrierConfig() {
+ PersistableBundle config = CarrierConfigManager.getDefaultConfig();
+ long actualLimitBytes;
+
+ assertLimitBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
+ mDefaultLimitBytes);
+ assertLimitBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, LIMIT_DISABLED);
+ assertLimitBytesAsExpected(config, 0, 0);
+ // not a valid value
+ assertLimitBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
+
+ // null config returns a default value
+ actualLimitBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultLimitBytes);
+ assertEquals(mDefaultLimitBytes, actualLimitBytes);
+ }
+
+ private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
+ when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
+ when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
+ when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
+ PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
+ when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
+ setNetworkPolicies(buildDefaultFakeMobilePolicy());
+ return bundle;
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
+ when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
+ when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
+ when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
+ when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
+ setNetworkPolicies(buildDefaultFakeMobilePolicy());
+ // smoke test to make sure no errors are raised
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+ assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
+ true);
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException {
+ PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ // Test with an invalid CarrierConfig, there should be no changes or crashes.
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+
+ assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
+ true);
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException {
+ PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ // Test that we respect the platform values when told to
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
+ DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+
+ assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
+ true);
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException {
+ PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+
+ // inferred = false implies that a user manually modified this policy.
+ NetworkPolicy policy = buildDefaultFakeMobilePolicy();
+ policy.inferred = false;
+ setNetworkPolicies(policy);
+
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_THRESHOLD_DISABLED);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+
+ // The policy still shouldn't change, because we don't want to overwrite user settings.
+ assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
+ false);
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException {
+ PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+
+ assertNetworkPolicyEquals(31, 9999, 9999, true);
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException {
+ PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_THRESHOLD_DISABLED);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_THRESHOLD_DISABLED);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+
+ assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
+ }
+
+ @Test
+ public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException {
+ PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_THRESHOLD_DISABLED);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_THRESHOLD_DISABLED);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+ assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
+
+ // If the user switches carriers to one that doesn't use a CarrierConfig, we should revert
+ // to the default data limit and warning. The cycle date doesn't need to revert as it's
+ // arbitrary anyways.
+ bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
+ DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
+ DATA_CYCLE_USE_PLATFORM_DEFAULT);
+ mServiceContext.sendBroadcast(
+ new Intent(ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ );
+
+ assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes,
+ true);
+ }
+
+ private NetworkPolicy buildDefaultFakeMobilePolicy() {
+ NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
+ // set a deterministic cycle date
+ p.cycleDay = DEFAULT_CYCLE_DAY;
+ return p;
+ }
+
+ private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes,
+ long limitBytes, boolean inferred){
+ final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID);
+ return new NetworkPolicy(template, cycleDay, new Time().timezone, warningBytes,
+ limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
+ }
+
+ private void assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes,
+ long expectedLimitBytes, boolean expectedInferred) {
+ NetworkPolicy[] policies = mService.getNetworkPolicies(
+ mServiceContext.getOpPackageName());
+ assertEquals("Unexpected number of network policies", 1, policies.length);
+ NetworkPolicy actualPolicy = policies[0];
+ NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes,
+ expectedLimitBytes, expectedInferred);
+ assertEquals(expectedPolicy, actualPolicy);
+ }
+
private static long parseTime(String time) {
final Time result = new Time();
result.parse3339(time);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index a9c69f6bd3d2..e0ac393290ac 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -128,9 +128,11 @@ public class NetworkScoreServiceTest {
private static final ScoredNetwork SCORED_NETWORK_2 =
new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID_2), "00:00:00:00:00:00")),
null /* rssiCurve*/);
+ private static final String NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID =
+ "networkAvailableNotificationChannelId";
private static final NetworkScorerAppData NEW_SCORER = new NetworkScorerAppData(
1, RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
- USE_WIFI_ENABLE_ACTIVITY_COMP);
+ USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID);
@Mock private NetworkScorerAppManager mNetworkScorerAppManager;
@Mock private Context mContext;
@@ -965,7 +967,7 @@ public class NetworkScoreServiceTest {
.thenReturn(PackageManager.PERMISSION_GRANTED);
NetworkScorerAppData expectedAppData = new NetworkScorerAppData(Binder.getCallingUid(),
RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
- USE_WIFI_ENABLE_ACTIVITY_COMP);
+ USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID);
bindToScorer(expectedAppData);
assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer());
}
@@ -1007,7 +1009,7 @@ public class NetworkScoreServiceTest {
final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1;
NetworkScorerAppData appData = new NetworkScorerAppData(callingUid,
RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
- USE_WIFI_ENABLE_ACTIVITY_COMP);
+ USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID);
bindToScorer(appData);
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
index e8663a2f2a22..9197ccf972c4 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
@@ -62,6 +62,8 @@ import java.util.List;
public class NetworkScorerAppManagerTest {
private static String MOCK_SERVICE_LABEL = "Mock Service";
private static String MOCK_OVERRIDEN_SERVICE_LABEL = "Mock Service Label Override";
+ private static String MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID =
+ "Mock Network Available Notification Channel Id";
@Mock private Context mMockContext;
@Mock private PackageManager mMockPm;
@@ -168,13 +170,30 @@ public class NetworkScorerAppManagerTest {
mockScoreNetworksGranted(recoComponent.getPackageName());
mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
enableUseOpenWifiComponent.getPackageName());
- mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
assertEquals(924, activeScorer.packageUid);
assertEquals(enableUseOpenWifiComponent, activeScorer.getEnableUseOpenWifiActivity());
+ assertNull(activeScorer.getNetworkAvailableNotificationChannelId());
+ }
+
+ @Test
+ public void testGetActiveScorer_providerAvailable_networkAvailableNotificationChannelIdSet() {
+ final ComponentName recoComponent = new ComponentName("package1", "class1");
+ setNetworkRecoPackageSetting(recoComponent.getPackageName());
+ mockScoreNetworksGranted(recoComponent.getPackageName());
+ mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ null /* enableUseOpenWifiActivityPackage */, false /* serviceLabelOverride */,
+ true /* setNotificationChannelId */);
+
+ final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
+ assertNotNull(activeScorer);
+ assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
+ assertEquals(924, activeScorer.packageUid);
+ assertEquals(MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID,
+ activeScorer.getNetworkAvailableNotificationChannelId());
}
@Test
@@ -368,6 +387,13 @@ public class NetworkScorerAppManagerTest {
private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid,
String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride) {
+ mockRecommendationServiceAvailable(compName, packageUid, enableUseOpenWifiActivityPackage,
+ serviceLabelOverride, false);
+ }
+
+ private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid,
+ String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride,
+ boolean setNotificationChannel) {
final ResolveInfo serviceInfo = new ResolveInfo();
serviceInfo.serviceInfo = new ServiceInfo();
serviceInfo.serviceInfo.name = compName.getClassName();
@@ -390,6 +416,14 @@ public class NetworkScorerAppManagerTest {
} else {
serviceInfo.serviceInfo.nonLocalizedLabel = MOCK_SERVICE_LABEL;
}
+ if (setNotificationChannel) {
+ if (serviceInfo.serviceInfo.metaData == null) {
+ serviceInfo.serviceInfo.metaData = new Bundle();
+ }
+ serviceInfo.serviceInfo.metaData.putString(
+ NetworkScoreManager.NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA,
+ MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID);
+ }
final int flags = PackageManager.GET_META_DATA;
when(mMockPm.resolveService(
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 374aee10da45..00f6273d14bf 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -94,7 +94,7 @@ import java.util.concurrent.atomic.AtomicLong;
* <p>Run with:<pre>
* mmma -j40 frameworks/base/services/tests/servicestests
* adb install -r ${OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * adb shell am instrument -w -e class package com.android.server.accounts \
+ * adb shell am instrument -w -e package com.android.server.accounts \
* com.android.frameworks.servicestests\
* /android.support.test.runner.AndroidJUnitRunner
* </pre>
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
index 2cb8af4e97e7..aa374073e4a5 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -385,6 +385,42 @@ public class AccountsDbTest {
}
@Test
+ public void testFindAllVisibilityValues() {
+ long accId = 10;
+ long accId2 = 11;
+ String packageName1 = "com.example.one";
+ String packageName2 = "com.example.two";
+ Account account = new Account("name", "example.com");
+ Account account2 = new Account("name2", "example2.com");
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
+
+ mAccountsDb.insertDeAccount(account, accId);
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
+ assertNull(mAccountsDb.findAccountVisibility(accId, packageName1));
+ mAccountsDb.insertDeAccount(account2, accId2);
+
+ mAccountsDb.setAccountVisibility(accId, packageName1, 1);
+ mAccountsDb.setAccountVisibility(accId, packageName2, 2);
+ mAccountsDb.setAccountVisibility(accId2, packageName1, 1);
+
+ Map<Account, Map<String, Integer>> vis = mAccountsDb.findAllVisibilityValues();
+ assertEquals(vis.size(), 2);
+ Map<String, Integer> accnt1Visibility = vis.get(account);
+ assertEquals(accnt1Visibility.size(), 2);
+ assertEquals(accnt1Visibility.get(packageName1), Integer.valueOf(1));
+ assertEquals(accnt1Visibility.get(packageName2), Integer.valueOf(2));
+ Map<String, Integer> accnt2Visibility = vis.get(account2);
+ assertEquals(accnt2Visibility.size(), 1);
+ assertEquals(accnt2Visibility.get(packageName1), Integer.valueOf(1));
+
+ mAccountsDb.setAccountVisibility(accId2, packageName2, 3);
+ vis = mAccountsDb.findAllVisibilityValues();
+ accnt2Visibility = vis.get(account2);
+ assertEquals(accnt2Visibility.size(), 2);
+ assertEquals(accnt2Visibility.get(packageName2), Integer.valueOf(3));
+ }
+
+ @Test
public void testVisibilityCleanupTrigger() {
long accId = 10;
String packageName1 = "com.example.one";
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index b12da34f4375..1e038dfaf1af 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -51,7 +51,9 @@ import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IApplicationThread;
import android.app.IUidObserver;
+import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -116,7 +118,9 @@ public class ActivityManagerServiceTest {
UidRecord.CHANGE_ACTIVE
};
+ @Mock private Context mContext;
@Mock private AppOpsService mAppOpsService;
+ @Mock private PackageManager mPackageManager;
private TestInjector mInjector;
private ActivityManagerService mAms;
@@ -133,6 +137,8 @@ public class ActivityManagerServiceTest {
mInjector = new TestInjector();
mAms = new ActivityManagerService(mInjector);
mAms.mWaitForNetworkTimeoutMs = 100;
+
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
}
@After
@@ -601,10 +607,12 @@ public class ActivityManagerServiceTest {
uidRecord.pendingChange = changeItem;
uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2;
verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2);
+ }
+ @Test
+ public void testEnqueueUidChangeLocked_nullUidRecord() {
// Use "null" uidRecord to make sure there is no crash.
- // TODO: currently it crashes, uncomment after fixing it.
- // mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
+ mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
}
private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
@@ -770,6 +778,11 @@ public class ActivityManagerServiceTest {
private boolean mRestricted = true;
@Override
+ public Context getContext() {
+ return mContext;
+ }
+
+ @Override
public AppOpsService getAppOpsService(File file, Handler handler) {
return mAppOpsService;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index b5826f0c1106..2003b91bcfad 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -26,8 +26,10 @@ import android.support.test.runner.AndroidJUnit4;
import android.view.Surface;
import android.view.WindowManager;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -160,4 +162,22 @@ public class AppWindowTokenTests extends WindowTestsBase {
sWm.mRoot.mOrientationChangeComplete = true;
sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
}
+
+ @Test
+ public void testGetOrientation() throws Exception {
+ final TestAppWindowToken token = new TestAppWindowToken(sDisplayContent);
+ token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+ token.setFillsParent(false);
+ // Can not specify orientation if app doesn't fill parent.
+ assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
+
+ token.setFillsParent(true);
+ token.hidden = true;
+ token.sendingToBottom = true;
+ // Can not specify orientation if app isn't visible even though it fills parent.
+ assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
+ // Can specify orientation if the current orientation candidate is orientation behind.
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 3868242616b2..1729ceec0005 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -233,6 +234,68 @@ public class DisplayContentTests extends WindowTestsBase {
assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
}
+ @Test
+ public void testFocusedWindowMultipleDisplays() throws Exception {
+ // Create a focusable window and check that focus is calcualted correctly
+ final WindowState window1 =
+ createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "window1");
+ assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+
+ // Check that a new display doesn't affect focus
+ final DisplayContent dc = createNewDisplay();
+ assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+
+ // Add a window to the second display, and it should be focused
+ final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
+ assertEquals(window2, sWm.mRoot.computeFocusedWindow());
+
+ // Move the first window to the to including parents, and make sure focus is updated
+ window1.getParent().positionChildAt(POSITION_TOP, window1, true);
+ assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+ }
+
+ /**
+ * This tests setting the maximum ui width on a display.
+ */
+ @Test
+ public void testMaxUiWidth() throws Exception {
+ final int baseWidth = 1440;
+ final int baseHeight = 2560;
+ final int baseDensity = 300;
+
+ sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+
+ final int maxWidth = 300;
+ final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
+ final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
+
+ sDisplayContent.setMaxUiWidth(maxWidth);
+ verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);
+
+ // Assert setting values again does not change;
+ sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+ verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);
+
+ final int smallerWidth = 200;
+ final int smallerHeight = 400;
+ final int smallerDensity = 100;
+
+ // Specify smaller dimension, verify that it is honored
+ sDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
+ verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+
+ // Verify that setting the max width to a greater value than the base width has no effect
+ sDisplayContent.setMaxUiWidth(maxWidth);
+ verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+ }
+
+ private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
+ int expectedBaseHeight, int expectedBaseDensity) {
+ assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
+ assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
+ assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
+ }
+
private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
final LinkedList<WindowState> actualWindows = new LinkedList();
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
index 3ce3df1557dd..9dbd8a617eec 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
@@ -76,9 +76,9 @@ public class TaskStackTests extends WindowTestsBase {
task2.addChild(appWindowToken2, 0);
appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
- assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_PORTRAIT);
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
sWm.mClosingApps.add(appWindowToken2);
- assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_LANDSCAPE);
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
}
@Test
@@ -94,9 +94,9 @@ public class TaskStackTests extends WindowTestsBase {
task2.addChild(appWindowToken2, 0);
appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
- assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_PORTRAIT);
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
task2.setSendingToBottom(true);
- assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_LANDSCAPE);
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 80b2e7d9bc3c..a7d594cbd256 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -422,7 +422,7 @@ public class WindowContainerTests extends WindowTestsBase {
final TestWindowContainer child1 = root.addChildWindow(builder);
child1.setFillsParent(true);
- assertTrue(root.getOrientation() == expectedOrientation);
+ assertEquals(expectedOrientation, root.getOrientation());
}
@Test
@@ -805,8 +805,13 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Override
+ int getOrientation(int candidate) {
+ return mOrientation != null ? mOrientation : super.getOrientation(candidate);
+ }
+
+ @Override
int getOrientation() {
- return mOrientation != null ? mOrientation : super.getOrientation();
+ return getOrientation(super.mOrientation);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 48799d23c06e..a9d930f5c893 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.view.View.VISIBLE;
+
import android.app.ActivityManager.TaskDescription;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -233,7 +235,7 @@ class WindowTestsBase {
attrs.setTitle(name);
final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
- 0, attrs, 0, 0, ownerCanAddInternalSystemWindow);
+ 0, attrs, VISIBLE, 0, ownerCanAddInternalSystemWindow);
// TODO: Probably better to make this call in the WindowState ctor to avoid errors with
// adding it to the token...
token.addWindow(w);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 1b28db72b9b3..e55e073cf063 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -20,6 +20,7 @@ import android.app.usage.TimeSparseArray;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.os.Build;
+import android.os.SystemProperties;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.TimeUtils;
@@ -56,6 +57,9 @@ class UsageStatsDatabase {
private static final boolean DEBUG = UsageStatsService.DEBUG;
private static final String BAK_SUFFIX = ".bak";
private static final String CHECKED_IN_SUFFIX = UsageStatsXml.CHECKED_IN_SUFFIX;
+ private static final String RETENTION_LEN_KEY = "ro.usagestats.chooser.retention";
+ private static final int SELECTION_LOG_RETENTION_LEN =
+ SystemProperties.getInt(RETENTION_LEN_KEY, 14);
private final Object mLock = new Object();
private final File[] mIntervalDirs;
@@ -504,7 +508,7 @@ class UsageStatsDatabase {
mCal.getTimeInMillis());
mCal.setTimeInMillis(currentTimeMillis);
- mCal.addDays(-14);
+ mCal.addDays(-SELECTION_LOG_RETENTION_LEN);
for (int i = 0; i < mIntervalDirs.length; ++i) {
pruneChooserCountsOlderThan(mIntervalDirs[i], mCal.getTimeInMillis());
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index f1cf4414de9e..0878e8ba369c 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -554,7 +554,7 @@ public class UsbDeviceManager {
boolean usbDataUnlocked) {
if (DEBUG) {
Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
- + "forceRestart=" + forceRestart);
+ + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);
}
if (usbDataUnlocked != mUsbDataUnlocked) {
@@ -641,8 +641,11 @@ public class UsbDeviceManager {
// Set the new USB configuration.
setUsbConfig(oemFunctions);
- // Start up dependent services.
- updateUsbStateBroadcastIfNeeded(true);
+ if (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
+ || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP)) {
+ // Start up dependent services.
+ updateUsbStateBroadcastIfNeeded(true);
+ }
if (!waitForState(oemFunctions)) {
Slog.e(TAG, "Failed to switch USB config to " + functions);
@@ -878,7 +881,12 @@ public class UsbDeviceManager {
setEnabledFunctions(functions, false, msg.arg1 == 1);
break;
case MSG_UPDATE_USER_RESTRICTIONS:
- setEnabledFunctions(mCurrentFunctions, false, mUsbDataUnlocked);
+ // Restart the USB stack if USB transfer is enabled but no longer allowed.
+ final boolean forceRestart = mUsbDataUnlocked
+ && isUsbDataTransferActive()
+ && !isUsbTransferAllowed();
+ setEnabledFunctions(
+ mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
break;
case MSG_SYSTEM_READY:
updateUsbNotification();
@@ -902,12 +910,10 @@ public class UsbDeviceManager {
case MSG_USER_SWITCHED: {
if (mCurrentUser != msg.arg1) {
// Restart the USB stack and re-apply user restrictions for MTP or PTP.
- final boolean active = UsbManager.containsFunction(mCurrentFunctions,
- UsbManager.USB_FUNCTION_MTP)
- || UsbManager.containsFunction(mCurrentFunctions,
- UsbManager.USB_FUNCTION_PTP);
- if (mUsbDataUnlocked && active && mCurrentUser != UserHandle.USER_NULL) {
- Slog.v(TAG, "Current user switched to " + mCurrentUser
+ if (mUsbDataUnlocked
+ && isUsbDataTransferActive()
+ && mCurrentUser != UserHandle.USER_NULL) {
+ Slog.v(TAG, "Current user switched to " + msg.arg1
+ "; resetting USB host stack for MTP or PTP");
// avoid leaking sensitive data from previous user
setEnabledFunctions(mCurrentFunctions, true, false);
@@ -928,6 +934,11 @@ public class UsbDeviceManager {
}
}
+ private boolean isUsbDataTransferActive() {
+ return UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)
+ || UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP);
+ }
+
public UsbAccessory getCurrentAccessory() {
return mCurrentAccessory;
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c79090203c0b..92233b1fed39 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -125,8 +125,9 @@ public final class Call {
public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
/**
- * Extra key used to indicate the time (in millis) when the last outgoing emergency call was
- * made. This is used to identify potential emergency callbacks.
+ * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC)
+ * when the last outgoing emergency call was made. This is used to identify potential emergency
+ * callbacks.
*/
public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
"android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7a226a04d7eb..2b4bce31bbda 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -771,6 +771,13 @@ public class CarrierConfigManager {
public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
/**
+ * Determines whether the Enhanced 4G LTE toggle will be shown in the settings. When this
+ * option is {@code true}, the toggle will be hidden regardless of whether the device and
+ * carrier supports 4G LTE or not.
+ */
+ public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
+
+ /**
* Determine whether IMS apn can be shown.
*/
public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
@@ -1522,6 +1529,7 @@ public class CarrierConfigManager {
sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true);
sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
+ sDefaults.putBoolean(KEY_HIDE_ENHANCED_4G_LTE_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false);
sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false);
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 85904823a731..7d4d90bb75ab 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -387,8 +387,8 @@ public final class SmsManager {
/**
* Inject an SMS PDU into the android application framework.
*
- * The caller should have carrier privileges.
- * @see android.telephony.TelephonyManager#hasCarrierPrivileges
+ * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
+ * privileges. @see android.telephony.TelephonyManager#hasCarrierPrivileges
*
* @param pdu is the byte array of pdu to be injected into android application framework
* @param format is the format of SMS pdu (3gpp or 3gpp2)
diff --git a/telephony/java/com/android/ims/ImsException.java b/telephony/java/com/android/ims/ImsException.java
index 74b20f472641..0e8bad79c59b 100644
--- a/telephony/java/com/android/ims/ImsException.java
+++ b/telephony/java/com/android/ims/ImsException.java
@@ -32,7 +32,7 @@ public class ImsException extends Exception {
}
public ImsException(String message, int code) {
- super(message + ", code = " + code);
+ super(message + "(" + code + ")");
mCode = code;
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index bcaac6e77bdd..73ee25ad5bcf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -261,7 +261,7 @@ public class TelephonyIntents {
* by the system.
*/
public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
- = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
+ = "com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
/**
* <p>Broadcast Action: Indicates that the action is forbidden by network.
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index da1d9984eea5..dca74ffdcc8c 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -526,6 +526,12 @@ public class MockContext extends Context {
}
@Override
+ public ComponentName startForegroundService(Intent service) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** STOPSHIP remove when trial API is turned down */
+ @Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
throw new UnsupportedOperationException();
@@ -544,6 +550,12 @@ public class MockContext extends Context {
/** @hide */
@Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** @hide STOPSHIP removed when trial API is turned down */
+ @Override
public ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user) {
throw new UnsupportedOperationException();
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 506f406c333f..960a2d9fd726 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -1118,4 +1118,12 @@ public class MockPackageManager extends PackageManager {
public int getInstallReason(String packageName, UserHandle user) {
throw new UnsupportedOperationException();
}
+
+ /**
+ * @hide
+ */
+ @Override
+ public ComponentName getInstantAppResolverSettingsComponent() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 04443a53527c..f22ad1d2e795 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -23,7 +23,12 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.NetworkCapabilities.*;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -33,6 +38,7 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.ConnectivityManager.PacketKeepalive;
@@ -76,11 +82,16 @@ import android.util.LogPrinter;
import com.android.internal.util.WakeupMessage;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
import com.android.server.net.NetworkPinner;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
@@ -133,8 +144,19 @@ public class ConnectivityServiceTest extends AndroidTestCase {
private class MockContext extends BroadcastInterceptingContext {
private final MockContentResolver mContentResolver;
+ @Spy private Resources mResources;
+
MockContext(Context base) {
super(base);
+
+ mResources = spy(base.getResources());
+ when(mResources.getStringArray(com.android.internal.R.array.networkAttributes)).
+ thenReturn(new String[] {
+ "wifi,1,1,1,-1,true",
+ "mobile,0,0,0,-1,true",
+ "mobile_mms,2,0,2,60000,true",
+ });
+
mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
}
@@ -150,6 +172,11 @@ public class ConnectivityServiceTest extends AndroidTestCase {
public ContentResolver getContentResolver() {
return mContentResolver;
}
+
+ @Override
+ public Resources getResources() {
+ return mResources;
+ }
}
/**
@@ -620,6 +647,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
private class WrappedConnectivityService extends ConnectivityService {
public WrappedMultinetworkPolicyTracker wrappedMultinetworkPolicyTracker;
private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
+ private MockableSystemProperties mSystemProperties;
public WrappedConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
@@ -629,9 +657,13 @@ public class ConnectivityServiceTest extends AndroidTestCase {
}
@Override
- protected int getDefaultTcpRwnd() {
- // Prevent wrapped ConnectivityService from trying to write to SystemProperties.
- return 0;
+ protected MockableSystemProperties getSystemProperties() {
+ // Minimal approach to overriding system properties: let most calls fall through to real
+ // device values, and only override ones values that are important to this test.
+ mSystemProperties = spy(new MockableSystemProperties());
+ when(mSystemProperties.getInt("net.tcp.default_init_rwnd", 0)).thenReturn(0);
+ when(mSystemProperties.getBoolean("ro.radio.noril", false)).thenReturn(false);
+ return mSystemProperties;
}
@Override
@@ -801,6 +833,14 @@ public class ConnectivityServiceTest extends AndroidTestCase {
return cv;
}
+ public void testNetworkTypes() {
+ // Ensure that our mocks for the networkAttributes config variable work as expected. If they
+ // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types
+ // will fail. Failing here is much easier to debug.
+ assertTrue(mCm.isNetworkSupported(TYPE_WIFI));
+ assertTrue(mCm.isNetworkSupported(TYPE_MOBILE));
+ }
+
@SmallTest
public void testLingering() throws Exception {
verifyNoNetwork();
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index b51b2771db16..efe6fec6fc7d 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -27,10 +27,12 @@ import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.UidRange;
+import android.os.Build;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.UserHandle;
@@ -45,6 +47,7 @@ import java.util.Arrays;
import java.util.Map;
import java.util.Set;
+import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
@@ -87,12 +90,13 @@ public class VpnTest extends AndroidTestCase {
}
}
- @Mock private Context mContext;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
@Mock private UserManager mUserManager;
@Mock private PackageManager mPackageManager;
@Mock private INetworkManagementService mNetService;
@Mock private AppOpsManager mAppOps;
@Mock private NotificationManager mNotificationManager;
+ @Mock private Vpn.SystemServices mSystemServices;
@Override
public void setUp() throws Exception {
@@ -104,6 +108,12 @@ public class VpnTest extends AndroidTestCase {
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
.thenReturn(mNotificationManager);
+
+ // Used by {@link Notification.Builder}
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ when(mContext.getApplicationInfo()).thenReturn(applicationInfo);
+
doNothing().when(mNetService).registerObserver(any());
}
@@ -111,7 +121,7 @@ public class VpnTest extends AndroidTestCase {
public void testRestrictedProfilesAreAddedToVpn() {
setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
- final Vpn vpn = spyVpn(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
null, null);
@@ -125,7 +135,7 @@ public class VpnTest extends AndroidTestCase {
public void testManagedProfilesAreNotAddedToVpn() {
setMockedUsers(primaryUser, managedProfileA);
- final Vpn vpn = spyVpn(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
null, null);
@@ -138,7 +148,7 @@ public class VpnTest extends AndroidTestCase {
public void testAddUserToVpnOnlyAddsOneUser() {
setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
- final Vpn vpn = spyVpn(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
final Set<UidRange> ranges = new ArraySet<>();
vpn.addUserToRanges(ranges, primaryUser.id, null, null);
@@ -149,7 +159,7 @@ public class VpnTest extends AndroidTestCase {
@SmallTest
public void testUidWhiteAndBlacklist() throws Exception {
- final Vpn vpn = spyVpn(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
final UidRange user = UidRange.createForUser(primaryUser.id);
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
@@ -174,7 +184,7 @@ public class VpnTest extends AndroidTestCase {
@SmallTest
public void testLockdownChangingPackage() throws Exception {
- final Vpn vpn = spyVpn(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
final UidRange user = UidRange.createForUser(primaryUser.id);
// Default state.
@@ -209,7 +219,7 @@ public class VpnTest extends AndroidTestCase {
@SmallTest
public void testLockdownAddingAProfile() throws Exception {
- final Vpn vpn = spyVpn(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser);
// Make a copy of the restricted profile, as we're going to mark it deleted halfway through.
@@ -249,40 +259,41 @@ public class VpnTest extends AndroidTestCase {
@SmallTest
public void testNotificationShownForAlwaysOnApp() {
- final Vpn vpn = spyVpn(primaryUser.id);
- final InOrder order = inOrder(vpn);
+ final UserHandle userHandle = UserHandle.of(primaryUser.id);
+ final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser);
+ final InOrder order = inOrder(mNotificationManager);
+
// Don't show a notification for regular disconnected states.
vpn.updateState(DetailedState.DISCONNECTED, TAG);
- order.verify(vpn).updateAlwaysOnNotificationInternal(false);
+ order.verify(mNotificationManager, atLeastOnce())
+ .cancelAsUser(anyString(), anyInt(), eq(userHandle));
// Start showing a notification for disconnected once always-on.
vpn.setAlwaysOnPackage(PKGS[0], false);
- order.verify(vpn).updateAlwaysOnNotificationInternal(true);
+ order.verify(mNotificationManager)
+ .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle));
// Stop showing the notification once connected.
vpn.updateState(DetailedState.CONNECTED, TAG);
- order.verify(vpn).updateAlwaysOnNotificationInternal(false);
+ order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
// Show the notification if we disconnect again.
vpn.updateState(DetailedState.DISCONNECTED, TAG);
- order.verify(vpn).updateAlwaysOnNotificationInternal(true);
+ order.verify(mNotificationManager)
+ .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle));
// Notification should be cleared after unsetting always-on package.
vpn.setAlwaysOnPackage(null, false);
- order.verify(vpn).updateAlwaysOnNotificationInternal(false);
+ order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
}
/**
* Mock some methods of vpn object.
*/
- private Vpn spyVpn(@UserIdInt int userId) {
- final Vpn vpn = spy(new Vpn(Looper.myLooper(), mContext, mNetService, userId));
-
- // Block calls to the NotificationManager or PendingIntent#getActivity.
- doNothing().when(vpn).updateAlwaysOnNotificationInternal(anyBoolean());
- return vpn;
+ private Vpn createVpn(@UserIdInt int userId) {
+ return new Vpn(Looper.myLooper(), mContext, mNetService, userId, mSystemServices);
}
private static void assertBlocked(Vpn vpn, int... uids) {
diff --git a/tests/testables/src/android/testing/BaseFragmentTest.java b/tests/testables/src/android/testing/BaseFragmentTest.java
index 53841d597e26..b09bcde897d7 100644
--- a/tests/testables/src/android/testing/BaseFragmentTest.java
+++ b/tests/testables/src/android/testing/BaseFragmentTest.java
@@ -133,14 +133,7 @@ public abstract class BaseFragmentTest {
public void testRecreate() {
mFragments.dispatchResume();
processAllMessages();
- mFragments.dispatchPause();
- Parcelable p = mFragments.saveAllState();
- mFragments.dispatchDestroy();
-
- mFragments = FragmentController.createController(new HostCallbacks());
- mFragments.attachHost(null);
- mFragments.restoreAllState(p, (FragmentManagerNonConfig) null);
- mFragments.dispatchResume();
+ recreateFragment();
processAllMessages();
}
@@ -154,6 +147,18 @@ public abstract class BaseFragmentTest {
processAllMessages();
}
+ protected void recreateFragment() {
+ mFragments.dispatchPause();
+ Parcelable p = mFragments.saveAllState();
+ mFragments.dispatchDestroy();
+
+ mFragments = FragmentController.createController(new HostCallbacks());
+ mFragments.attachHost(null);
+ mFragments.restoreAllState(p, (FragmentManagerNonConfig) null);
+ mFragments.dispatchResume();
+ mFragment = mFragments.getFragmentManager().findFragmentById(VIEW_ID);
+ }
+
protected void attachFragmentToWindow() {
ViewUtils.attachView(mView);
TestableLooper.get(this).processMessages(1);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 3330b1a78c1e..2bf52066b618 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1403,7 +1403,8 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
String8 src = it.getFile()->getPrintableSource();
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
it.getFile(), &table, xmlFlags);
- if (err == NO_ERROR) {
+ // Only verify IDs if there was no error and the file is non-empty.
+ if (err == NO_ERROR && it.getFile()->hasData()) {
ResXMLTree block;
block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
checkForIds(src, block);
@@ -1550,7 +1551,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
String8 src = it.getFile()->getPrintableSource();
err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
it.getFile(), &table, xmlFlags);
- if (err == NO_ERROR) {
+ if (err == NO_ERROR && it.getFile()->hasData()) {
ResXMLTree block;
block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
checkForIds(src, block);
@@ -1598,7 +1599,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.xmlRoot,
workItem.file, &table, xmlCompilationFlags);
- if (err == NO_ERROR) {
+ if (err == NO_ERROR && workItem.file->hasData()) {
assets->addResource(workItem.resPath.getPathLeaf(),
workItem.resPath,
workItem.file,
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 391aa47469ef..221f3c2cd0c3 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -78,6 +78,17 @@ status_t compileXmlFile(const Bundle* bundle,
ResourceTable* table,
int options)
{
+ if (table->versionForCompat(bundle, resourceName, target, root)) {
+ // The file was versioned, so stop processing here.
+ // The resource entry has already been removed and the new one added.
+ // Remove the assets entry.
+ sp<AaptDir> resDir = assets->getDirs().valueFor(String8("res"));
+ sp<AaptDir> dir = resDir->getDirs().valueFor(target->getGroupEntry().toDirName(
+ target->getResourceType()));
+ dir->removeFile(target->getPath().getPathLeaf());
+ return NO_ERROR;
+ }
+
if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
root->removeWhitespace(true, NULL);
} else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
@@ -4758,6 +4769,77 @@ static bool IsTransitionElement(const String16& name) {
return false;
}
+bool ResourceTable::versionForCompat(const Bundle* bundle, const String16& resourceName,
+ const sp<AaptFile>& target, const sp<XMLNode>& root) {
+ XMLNode* node = root.get();
+ while (node->getType() != XMLNode::TYPE_ELEMENT) {
+ // We're assuming the root element is what we're looking for, which can only be under a
+ // bunch of namespace declarations.
+ if (node->getChildren().size() != 1) {
+ // Not sure what to do, bail.
+ return false;
+ }
+ node = node->getChildren().itemAt(0).get();
+ }
+
+ if (node->getElementNamespace().size() != 0) {
+ // Not something we care about.
+ return false;
+ }
+
+ int versionedSdk = 0;
+ if (node->getElementName() == String16("adaptive-icon")) {
+ versionedSdk = SDK_O;
+ }
+
+ const int minSdkVersion = getMinSdkVersion(bundle);
+ const ConfigDescription config(target->getGroupEntry().toParams());
+ if (versionedSdk <= minSdkVersion || versionedSdk <= config.sdkVersion) {
+ return false;
+ }
+
+ sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),
+ String16(target->getResourceType()), resourceName);
+ if (!shouldGenerateVersionedResource(cl, config, versionedSdk)) {
+ return false;
+ }
+
+ // Remove the original entry.
+ cl->removeEntry(config);
+
+ // We need to wholesale version this file.
+ ConfigDescription newConfig(config);
+ newConfig.sdkVersion = versionedSdk;
+ sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
+ AaptGroupEntry(newConfig), target->getResourceType());
+ String8 resPath = String8::format("res/%s/%s.xml",
+ newFile->getGroupEntry().toDirName(target->getResourceType()).string(),
+ String8(resourceName).string());
+ resPath.convertToResPath();
+
+ // Add a resource table entry.
+ addEntry(SourcePos(),
+ String16(mAssets->getPackage()),
+ String16(target->getResourceType()),
+ resourceName,
+ String16(resPath),
+ NULL,
+ &newConfig);
+
+ // Schedule this to be compiled.
+ CompileResourceWorkItem item;
+ item.resourceName = resourceName;
+ item.resPath = resPath;
+ item.file = newFile;
+ item.xmlRoot = root->clone();
+ item.needsCompiling = false; // This step occurs after we parse/assign, so we don't need
+ // to do it again.
+ mWorkQueue.push(item);
+
+ // Now mark the old entry as deleted.
+ return true;
+}
+
status_t ResourceTable::modifyForCompat(const Bundle* bundle,
const String16& resourceName,
const sp<AaptFile>& target,
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index cf1e992ec330..aff22d4d1364 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -203,6 +203,9 @@ public:
size_t numLocalResources() const;
bool hasResources() const;
+ bool versionForCompat(const Bundle* bundle, const String16& resourceName,
+ const sp<AaptFile>& file, const sp<XMLNode>& root);
+
status_t modifyForCompat(const Bundle* bundle);
status_t modifyForCompat(const Bundle* bundle,
const String16& resourceName,
@@ -431,6 +434,10 @@ public:
mEntries.add(config, entry);
}
+ void removeEntry(const ResTable_config& config) {
+ mEntries.removeItem(config);
+ }
+
const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
private:
const String16 mName;
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 5e9b81a29af9..36c1de6a4f26 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -25,7 +25,7 @@ namespace aapt {
static const char* sMajorVersion = "2";
// Update minor version whenever a feature or flag is added.
-static const char* sMinorVersion = "11";
+static const char* sMinorVersion = "12";
int PrintVersion() {
std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 6e4b450b65e5..1947628e9267 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -32,22 +32,19 @@ using android::StringPiece;
namespace aapt {
-static bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs,
- ResourceType rhs) {
+static bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) {
return lhs->type < rhs;
}
template <typename T>
-static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs,
- const StringPiece& rhs) {
+static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, const StringPiece& rhs) {
return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0;
}
ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) {
const auto last = packages.end();
- auto iter =
- std::lower_bound(packages.begin(), last, name,
- less_than_struct_with_name<ResourceTablePackage>);
+ auto iter = std::lower_bound(packages.begin(), last, name,
+ less_than_struct_with_name<ResourceTablePackage>);
if (iter != last && name == (*iter)->name) {
return iter->get();
}
@@ -63,8 +60,7 @@ ResourceTablePackage* ResourceTable::FindPackageById(uint8_t id) {
return nullptr;
}
-ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name,
- Maybe<uint8_t> id) {
+ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Maybe<uint8_t> id) {
ResourceTablePackage* package = FindOrCreatePackage(name);
if (id && !package->id) {
package->id = id;
@@ -77,18 +73,15 @@ ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name,
return package;
}
-ResourceTablePackage* ResourceTable::FindOrCreatePackage(
- const StringPiece& name) {
+ResourceTablePackage* ResourceTable::FindOrCreatePackage(const StringPiece& name) {
const auto last = packages.end();
- auto iter =
- std::lower_bound(packages.begin(), last, name,
- less_than_struct_with_name<ResourceTablePackage>);
+ auto iter = std::lower_bound(packages.begin(), last, name,
+ less_than_struct_with_name<ResourceTablePackage>);
if (iter != last && name == (*iter)->name) {
return iter->get();
}
- std::unique_ptr<ResourceTablePackage> new_package =
- util::make_unique<ResourceTablePackage>();
+ std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>();
new_package->name = name.to_string();
return packages.emplace(iter, std::move(new_package))->get();
}
@@ -113,8 +106,8 @@ ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) {
ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name) {
const auto last = entries.end();
- auto iter = std::lower_bound(entries.begin(), last, name,
- less_than_struct_with_name<ResourceEntry>);
+ auto iter =
+ std::lower_bound(entries.begin(), last, name, less_than_struct_with_name<ResourceEntry>);
if (iter != last && name == (*iter)->name) {
return iter->get();
}
@@ -123,8 +116,8 @@ ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name) {
ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name) {
auto last = entries.end();
- auto iter = std::lower_bound(entries.begin(), last, name,
- less_than_struct_with_name<ResourceEntry>);
+ auto iter =
+ std::lower_bound(entries.begin(), last, name, less_than_struct_with_name<ResourceEntry>);
if (iter != last && name == (*iter)->name) {
return iter->get();
}
@@ -140,8 +133,7 @@ struct ConfigKey {
const StringPiece& product;
};
-bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs,
- const ConfigKey& rhs) {
+bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, const ConfigKey& rhs) {
int cmp = lhs->config.compare(*rhs.config);
if (cmp == 0) {
cmp = StringPiece(lhs->product).compare(rhs.product);
@@ -151,8 +143,8 @@ bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs,
ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config,
const StringPiece& product) {
- auto iter = std::lower_bound(values.begin(), values.end(),
- ConfigKey{&config, product}, ltConfigKeyRef);
+ auto iter =
+ std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product}, ltConfigKeyRef);
if (iter != values.end()) {
ResourceConfigValue* value = iter->get();
if (value->config == config && StringPiece(value->product) == product) {
@@ -162,10 +154,10 @@ ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config,
return nullptr;
}
-ResourceConfigValue* ResourceEntry::FindOrCreateValue(
- const ConfigDescription& config, const StringPiece& product) {
- auto iter = std::lower_bound(values.begin(), values.end(),
- ConfigKey{&config, product}, ltConfigKeyRef);
+ResourceConfigValue* ResourceEntry::FindOrCreateValue(const ConfigDescription& config,
+ const StringPiece& product) {
+ auto iter =
+ std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product}, ltConfigKeyRef);
if (iter != values.end()) {
ResourceConfigValue* value = iter->get();
if (value->config == config && StringPiece(value->product) == product) {
@@ -173,14 +165,11 @@ ResourceConfigValue* ResourceEntry::FindOrCreateValue(
}
}
ResourceConfigValue* newValue =
- values
- .insert(iter, util::make_unique<ResourceConfigValue>(config, product))
- ->get();
+ values.insert(iter, util::make_unique<ResourceConfigValue>(config, product))->get();
return newValue;
}
-std::vector<ResourceConfigValue*> ResourceEntry::findAllValues(
- const ConfigDescription& config) {
+std::vector<ResourceConfigValue*> ResourceEntry::FindAllValues(const ConfigDescription& config) {
std::vector<ResourceConfigValue*> results;
auto iter = values.begin();
@@ -237,8 +226,8 @@ std::vector<ResourceConfigValue*> ResourceEntry::FindValuesIf(
* format for there to be
* no error.
*/
-ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(
- Value* existing, Value* incoming) {
+ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(Value* existing,
+ Value* incoming) {
Attribute* existing_attr = ValueCast<Attribute>(existing);
Attribute* incoming_attr = ValueCast<Attribute>(incoming);
if (!incoming_attr) {
@@ -278,18 +267,15 @@ ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(
// The two attributes are both DECLs, but they are plain attributes
// with the same formats.
// Keep the strongest one.
- return existing_attr->IsWeak() ? CollisionResult::kTakeNew
- : CollisionResult::kKeepOriginal;
+ return existing_attr->IsWeak() ? CollisionResult::kTakeNew : CollisionResult::kKeepOriginal;
}
- if (existing_attr->IsWeak() &&
- existing_attr->type_mask == android::ResTable_map::TYPE_ANY) {
+ if (existing_attr->IsWeak() && existing_attr->type_mask == android::ResTable_map::TYPE_ANY) {
// Any incoming attribute is better than this.
return CollisionResult::kTakeNew;
}
- if (incoming_attr->IsWeak() &&
- incoming_attr->type_mask == android::ResTable_map::TYPE_ANY) {
+ if (incoming_attr->IsWeak() && incoming_attr->type_mask == android::ResTable_map::TYPE_ANY) {
// The incoming attribute may be a USE instead of a DECL.
// Keep the existing attribute.
return CollisionResult::kKeepOriginal;
@@ -298,15 +284,26 @@ ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(
}
static constexpr const char* kValidNameChars = "._-";
-static constexpr const char* kValidNameMangledChars = "._-$";
+
+static StringPiece ValidateName(const StringPiece& name) {
+ auto iter = util::FindNonAlphaNumericAndNotInSet(name, kValidNameChars);
+ if (iter != name.end()) {
+ return StringPiece(iter, 1);
+ }
+ return {};
+}
+
+static StringPiece SkipValidateName(const StringPiece& /*name*/) {
+ return {};
+}
bool ResourceTable::AddResource(const ResourceNameRef& name,
const ConfigDescription& config,
const StringPiece& product,
std::unique_ptr<Value> value,
IDiagnostics* diag) {
- return AddResourceImpl(name, {}, config, product, std::move(value),
- kValidNameChars, ResolveValueCollision, diag);
+ return AddResourceImpl(name, {}, config, product, std::move(value), ValidateName,
+ ResolveValueCollision, diag);
}
bool ResourceTable::AddResource(const ResourceNameRef& name,
@@ -315,8 +312,8 @@ bool ResourceTable::AddResource(const ResourceNameRef& name,
const StringPiece& product,
std::unique_ptr<Value> value,
IDiagnostics* diag) {
- return AddResourceImpl(name, res_id, config, product, std::move(value),
- kValidNameChars, ResolveValueCollision, diag);
+ return AddResourceImpl(name, res_id, config, product, std::move(value), ValidateName,
+ ResolveValueCollision, diag);
}
bool ResourceTable::AddFileReference(const ResourceNameRef& name,
@@ -324,29 +321,26 @@ bool ResourceTable::AddFileReference(const ResourceNameRef& name,
const Source& source,
const StringPiece& path,
IDiagnostics* diag) {
- return AddFileReferenceImpl(name, config, source, path, nullptr,
- kValidNameChars, diag);
+ return AddFileReferenceImpl(name, config, source, path, nullptr, ValidateName, diag);
}
bool ResourceTable::AddFileReferenceAllowMangled(
const ResourceNameRef& name, const ConfigDescription& config,
const Source& source, const StringPiece& path, io::IFile* file,
IDiagnostics* diag) {
- return AddFileReferenceImpl(name, config, source, path, file,
- kValidNameMangledChars, diag);
+ return AddFileReferenceImpl(name, config, source, path, file, SkipValidateName, diag);
}
-bool ResourceTable::AddFileReferenceImpl(
- const ResourceNameRef& name, const ConfigDescription& config,
- const Source& source, const StringPiece& path, io::IFile* file,
- const char* valid_chars, IDiagnostics* diag) {
+bool ResourceTable::AddFileReferenceImpl(const ResourceNameRef& name,
+ const ConfigDescription& config, const Source& source,
+ const StringPiece& path, io::IFile* file,
+ NameValidator name_validator, IDiagnostics* diag) {
std::unique_ptr<FileReference> fileRef =
util::make_unique<FileReference>(string_pool.MakeRef(path));
fileRef->SetSource(source);
fileRef->file = file;
- return AddResourceImpl(name, ResourceId{}, config, StringPiece{},
- std::move(fileRef), valid_chars, ResolveValueCollision,
- diag);
+ return AddResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef),
+ name_validator, ResolveValueCollision, diag);
}
bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name,
@@ -354,8 +348,8 @@ bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name,
const StringPiece& product,
std::unique_ptr<Value> value,
IDiagnostics* diag) {
- return AddResourceImpl(name, ResourceId{}, config, product, std::move(value),
- kValidNameMangledChars, ResolveValueCollision, diag);
+ return AddResourceImpl(name, ResourceId{}, config, product, std::move(value), SkipValidateName,
+ ResolveValueCollision, diag);
}
bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name,
@@ -364,25 +358,24 @@ bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name,
const StringPiece& product,
std::unique_ptr<Value> value,
IDiagnostics* diag) {
- return AddResourceImpl(name, id, config, product, std::move(value),
- kValidNameMangledChars, ResolveValueCollision, diag);
+ return AddResourceImpl(name, id, config, product, std::move(value), SkipValidateName,
+ ResolveValueCollision, diag);
}
-bool ResourceTable::AddResourceImpl(
- const ResourceNameRef& name, const ResourceId& res_id,
- const ConfigDescription& config, const StringPiece& product,
- std::unique_ptr<Value> value, const char* valid_chars,
- const CollisionResolverFunc& conflictResolver, IDiagnostics* diag) {
+bool ResourceTable::AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
+ const ConfigDescription& config, const StringPiece& product,
+ std::unique_ptr<Value> value, NameValidator name_validator,
+ const CollisionResolverFunc& conflictResolver,
+ IDiagnostics* diag) {
CHECK(value != nullptr);
CHECK(diag != nullptr);
- auto bad_char_iter =
- util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars);
- if (bad_char_iter != name.entry.end()) {
- diag->Error(DiagMessage(value->GetSource())
- << "resource '" << name << "' has invalid entry name '"
- << name.entry << "'. Invalid character '"
- << StringPiece(bad_char_iter, 1) << "'");
+ const StringPiece bad_char = name_validator(name.entry);
+ if (!bad_char.empty()) {
+ diag->Error(DiagMessage(value->GetSource()) << "resource '" << name
+ << "' has invalid entry name '" << name.entry
+ << "'. Invalid character '" << bad_char << "'");
+
return false;
}
@@ -450,30 +443,26 @@ bool ResourceTable::AddResourceImpl(
bool ResourceTable::SetSymbolState(const ResourceNameRef& name,
const ResourceId& res_id,
const Symbol& symbol, IDiagnostics* diag) {
- return SetSymbolStateImpl(name, res_id, symbol, kValidNameChars, diag);
+ return SetSymbolStateImpl(name, res_id, symbol, ValidateName, diag);
}
bool ResourceTable::SetSymbolStateAllowMangled(const ResourceNameRef& name,
const ResourceId& res_id,
const Symbol& symbol,
IDiagnostics* diag) {
- return SetSymbolStateImpl(name, res_id, symbol, kValidNameMangledChars, diag);
+ return SetSymbolStateImpl(name, res_id, symbol, SkipValidateName, diag);
}
-bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name,
- const ResourceId& res_id,
- const Symbol& symbol,
- const char* valid_chars,
+bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id,
+ const Symbol& symbol, NameValidator name_validator,
IDiagnostics* diag) {
CHECK(diag != nullptr);
- auto bad_char_iter =
- util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars);
- if (bad_char_iter != name.entry.end()) {
- diag->Error(DiagMessage(symbol.source)
- << "resource '" << name << "' has invalid entry name '"
- << name.entry << "'. Invalid character '"
- << StringPiece(bad_char_iter, 1) << "'");
+ const StringPiece bad_char = name_validator(name.entry);
+ if (!bad_char.empty()) {
+ diag->Error(DiagMessage(symbol.source) << "resource '" << name << "' has invalid entry name '"
+ << name.entry << "'. Invalid character '" << bad_char
+ << "'");
return false;
}
@@ -532,8 +521,7 @@ bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name,
return true;
}
-Maybe<ResourceTable::SearchResult> ResourceTable::FindResource(
- const ResourceNameRef& name) {
+Maybe<ResourceTable::SearchResult> ResourceTable::FindResource(const ResourceNameRef& name) {
ResourceTablePackage* package = FindPackage(name.package);
if (!package) {
return {};
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 6b69aaf02cbe..b0321214c6cc 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -113,8 +113,7 @@ class ResourceEntry {
const android::StringPiece& product);
ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config,
const android::StringPiece& product);
- std::vector<ResourceConfigValue*> findAllValues(
- const ConfigDescription& config);
+ std::vector<ResourceConfigValue*> FindAllValues(const ConfigDescription& config);
std::vector<ResourceConfigValue*> FindValuesIf(
const std::function<bool(ResourceConfigValue*)>& f);
@@ -189,8 +188,7 @@ class ResourceTable {
* When a collision of resources occurs, this method decides which value to
* keep.
*/
- static CollisionResult ResolveValueCollision(Value* existing,
- Value* incoming);
+ static CollisionResult ResolveValueCollision(Value* existing, Value* incoming);
bool AddResource(const ResourceNameRef& name, const ConfigDescription& config,
const android::StringPiece& product, std::unique_ptr<Value> value,
@@ -274,20 +272,24 @@ class ResourceTable {
std::map<size_t, std::string> included_packages_;
private:
+ // The function type that validates a symbol name. Returns a non-empty StringPiece representing
+ // the offending character (which may be more than one byte in UTF-8). Returns an empty string
+ // if the name was valid.
+ using NameValidator = android::StringPiece(const android::StringPiece&);
+
ResourceTablePackage* FindOrCreatePackage(const android::StringPiece& name);
bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
const ConfigDescription& config, const android::StringPiece& product,
- std::unique_ptr<Value> value, const char* valid_chars,
+ std::unique_ptr<Value> value, NameValidator name_validator,
const CollisionResolverFunc& conflict_resolver, IDiagnostics* diag);
bool AddFileReferenceImpl(const ResourceNameRef& name, const ConfigDescription& config,
const Source& source, const android::StringPiece& path, io::IFile* file,
- const char* valid_chars, IDiagnostics* diag);
+ NameValidator name_validator, IDiagnostics* diag);
bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id,
- const Symbol& symbol, const char* valid_chars,
- IDiagnostics* diag);
+ const Symbol& symbol, NameValidator name_validator, IDiagnostics* diag);
DISALLOW_COPY_AND_ASSIGN(ResourceTable);
};
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index cb3699a00f75..e2b37be994ff 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -40,6 +40,14 @@ TEST(ResourceTableTest, FailToAddResourceWithBadName) {
test::GetDiagnostics()));
}
+TEST(ResourceTableTest, AddResourceWithWeirdNameWhenAddingMangledResources) {
+ ResourceTable table;
+
+ EXPECT_TRUE(table.AddResourceAllowMangled(
+ test::ParseNameOrDie("android:id/heythere "), ConfigDescription{}, "",
+ test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), test::GetDiagnostics()));
+}
+
TEST(ResourceTableTest, AddOneResource) {
ResourceTable table;
@@ -130,7 +138,7 @@ TEST(ResourceTableTest, ProductVaryingValues) {
table.FindResource(test::ParseNameOrDie("android:string/foo"));
AAPT_ASSERT_TRUE(sr);
std::vector<ResourceConfigValue*> values =
- sr.value().entry->findAllValues(test::ParseConfigOrDie("land"));
+ sr.value().entry->FindAllValues(test::ParseConfigOrDie("land"));
ASSERT_EQ(2u, values.size());
EXPECT_EQ(std::string("phone"), values[0]->product);
EXPECT_EQ(std::string("tablet"), values[1]->product);
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index 9899f803b339..2e674bddce7e 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -1,5 +1,13 @@
# Android Asset Packaging Tool 2.0 (AAPT2) release notes
+## Version 2.12
+### `aapt2 optimize ...`
+- aapt2 optimize now understands map (complex) values under the type `id`. It ignores their
+ contents and interprets them as a sentinel `id` type. This was added to support existing
+ apps that build with their `id` types as map values.
+ AAPT and AAPT2 always generate a simple value for the type `ID`, so it is unclear how some
+ these apps are encoded.
+
## Version 2.11
### `aapt2 link ...`
- Adds the ability to specify assets directories with the -A parameter. Assets work just like
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 66bcfa034dfb..35bf618c1635 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -168,10 +168,11 @@ bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) {
}
bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
- const ResTable_package* package_header = ConvertTo<ResTable_package>(chunk);
+ constexpr size_t kMinPackageSize =
+ sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset);
+ const ResTable_package* package_header = ConvertTo<ResTable_package, kMinPackageSize>(chunk);
if (!package_header) {
- context_->GetDiagnostics()->Error(DiagMessage(source_)
- << "corrupt ResTable_package chunk");
+ context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_package chunk");
return false;
}
@@ -498,8 +499,14 @@ std::unique_ptr<Value> BinaryResourceParser::ParseMapEntry(
return ParseArray(name, config, map);
case ResourceType::kPlurals:
return ParsePlural(name, config, map);
+ case ResourceType::kId:
+ // Special case: An ID is not a bag, but some apps have defined the auto-generated
+ // IDs that come from declaring an enum value in an attribute as an empty map...
+ // We can ignore the value here.
+ return util::make_unique<Id>();
default:
- LOG(FATAL) << "unknown map type";
+ context_->GetDiagnostics()->Error(DiagMessage() << "illegal map type '" << ToString(name.type)
+ << "' (" << (int)name.type << ")");
break;
}
return {};
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
index 819103db9d99..a2b0c3364a3e 100644
--- a/tools/layoutlib/.gitignore
+++ b/tools/layoutlib/.gitignore
@@ -2,3 +2,4 @@ bin
/.idea/workspace.xml
/out
/bridge/out
+/.idea/kotlinc.xml \ No newline at end of file
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 2c7e9363da72..cda8e6aca8df 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -740,9 +740,11 @@ public final class BridgeTypedArray extends TypedArray {
}
int id = getResourceId(index, 0);
String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : "";
- throw new NotFoundException(
- String.format("%1$s in %2$s%3$s is not a valid array resource.",
- resVal.getValue(), mNames[index], resIdMessage));
+ assert false :
+ String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(),
+ mNames[index], resIdMessage);
+
+ return new CharSequence[0];
}
@Override
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
index e3bc34b64582..c20ee12ee30c 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -33,7 +33,6 @@ import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.layoutlib.bridge.util.NinePatchInputStream;
import com.android.ninepatch.NinePatch;
import com.android.resources.ResourceType;
-import com.android.resources.ResourceUrl;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import com.android.util.Pair;
@@ -60,8 +59,6 @@ import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Iterator;
-import static com.android.SdkConstants.ANDROID_NS_NAME;
-
@SuppressWarnings("deprecation")
public class Resources_Delegate {
@@ -140,8 +137,8 @@ public class Resources_Delegate {
if (value == null) {
// Unable to resolve the attribute, just leave the unresolved value
- value = new ResourceValue(ResourceUrl.create(resourceInfo.getFirst(), attributeName,
- platformResFlag_out[0]), attributeName);
+ value = new ResourceValue(resourceInfo.getFirst(), attributeName, attributeName,
+ platformResFlag_out[0]);
}
return Pair.of(attributeName, value);
}
@@ -681,7 +678,7 @@ public class Resources_Delegate {
String packageName;
if (resourceInfo != null) {
if (platformOut[0]) {
- packageName = ANDROID_NS_NAME;
+ packageName = SdkConstants.ANDROID_NS_NAME;
} else {
packageName = resources.mContext.getPackageName();
packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
@@ -699,7 +696,7 @@ public class Resources_Delegate {
Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
if (resourceInfo != null) {
if (platformOut[0]) {
- return ANDROID_NS_NAME;
+ return SdkConstants.ANDROID_NS_NAME;
}
String packageName = resources.mContext.getPackageName();
return packageName == null ? SdkConstants.APP_PREFIX : packageName;
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
index e4fcf1be32bd..5cc964aee722 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
@@ -88,8 +88,9 @@ public final class BlendComposite implements Composite {
private void setAlpha(float alpha) {
if (alpha < 0.0f || alpha > 1.0f) {
- throw new IllegalArgumentException(
- "alpha must be comprised between 0.0f and 1.0f");
+ assert false : "alpha must be comprised between 0.0f and 1.0f";
+ alpha = Math.min(alpha, 1.0f);
+ alpha = Math.max(alpha, 0.0f);
}
this.alpha = alpha;
@@ -266,9 +267,21 @@ public final class BlendComposite implements Composite {
return result;
}
};
+ default:
+ assert false : "Blender not implement for " + composite.getMode().name();
+
+ // Ignore the blend
+ return new Blender() {
+ @Override
+ public int[] blend(int[] src, int[] dst, int[] result) {
+ result[0] = dst[0];
+ result[1] = dst[1];
+ result[2] = dst[2];
+ result[3] = dst[3];
+ return result;
+ }
+ };
}
- throw new IllegalArgumentException("Blender not implement for " +
- composite.getMode().name());
}
}
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 3bab4acc3635..7fe464abbf32 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -252,7 +252,8 @@ public class FontFamily_Delegate {
/*package*/ static boolean addFont(FontFamily thisFontFamily, String path, int ttcIndex,
FontConfig.Axis[] axes, int weight, int italic) {
if (thisFontFamily.mBuilderPtr == 0) {
- throw new IllegalStateException("Unable to call addFont after freezing.");
+ assert false : "Unable to call addFont after freezing.";
+ return false;
}
final FontFamily_Delegate delegate = getDelegate(thisFontFamily.mBuilderPtr);
return delegate != null && delegate.addFont(path, ttcIndex, weight, italic);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
index 6a89d8ff9342..64410e4c6a05 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
@@ -49,21 +49,19 @@ public abstract class Gradient_Delegate extends Shader_Delegate {
*/
protected Gradient_Delegate(long nativeMatrix, int colors[], float positions[]) {
super(nativeMatrix);
- if (colors.length < 2) {
- throw new IllegalArgumentException("needs >= 2 number of colors");
- }
- if (positions != null && colors.length != positions.length) {
- throw new IllegalArgumentException("color and position arrays must be of equal length");
- }
+ assert colors.length >= 2 : "needs >= 2 number of colors";
if (positions == null) {
float spacing = 1.f / (colors.length - 1);
positions = new float[colors.length];
positions[0] = 0.f;
- positions[colors.length-1] = 1.f;
- for (int i = 1; i < colors.length - 1 ; i++) {
+ positions[colors.length - 1] = 1.f;
+ for (int i = 1; i < colors.length - 1; i++) {
positions[i] = spacing * i;
}
+ } else {
+ assert colors.length == positions.length :
+ "color and position " + "arrays must be of equal length";
}
mColors = colors;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 579fce09d094..50b916532319 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -548,10 +548,11 @@ public final class Path_Delegate {
case EVEN_ODD:
case INVERSE_EVEN_ODD:
return GeneralPath.WIND_EVEN_ODD;
- }
- assert false;
- throw new IllegalArgumentException();
+ default:
+ assert false;
+ return GeneralPath.WIND_NON_ZERO;
+ }
}
@NonNull
diff --git a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
index edd36e54aa77..736f03ec5a8c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
@@ -61,10 +61,8 @@ public class RoundRectangle extends RectangularShape {
* ellipse that corner is a quarter of.
*/
public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) {
- if (cornerDimensions.length != 8) {
- throw new IllegalArgumentException("The array of corner dimensions must have eight " +
- "elements");
- }
+ assert cornerDimensions.length == 8 : "The array of corner dimensions must have eight " +
+ "elements";
this.x = x;
this.y = y;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index e118889b3714..80e3bada8ca3 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -233,7 +233,8 @@ public final class Typeface_Delegate {
Map<String, ByteBuffer> bufferForPath) {
FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
for (FontConfig.Font font : family.getFonts()) {
- FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, font.getFontName(),
+ String fullPathName = "/system/fonts/" + font.getFontName();
+ FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName,
font.getWeight(), font.isItalic());
}
fontFamily.freeze();
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
index cc7631ac939a..616784c10aae 100644
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -585,8 +585,8 @@ public class VectorDrawable_Delegate {
return this::setTrimPathOffset;
}
- throw new IllegalArgumentException("Invalid VFullPath_Delegate property index "
- + propertyIdx);
+ assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
+ return t -> {};
}
@NonNull
@@ -598,8 +598,8 @@ public class VectorDrawable_Delegate {
return this::setFillColor;
}
- throw new IllegalArgumentException("Invalid VFullPath_Delegate property index "
- + propertyIdx);
+ assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
+ return t -> {};
}
/////////////////////////////////////////////////////
@@ -827,8 +827,8 @@ public class VectorDrawable_Delegate {
return this::setTranslateY;
}
- throw new IllegalArgumentException("Invalid VGroup_Delegate property index "
- + propertyIdx);
+ assert false : ("Invalid VGroup_Delegate property index " + propertyIdx);
+ return t -> {};
}
/////////////////////////////////////////////////////
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 1b9901594f6e..cc031439226b 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -164,7 +164,9 @@ public class StaticLayout_Delegate {
builder.mTabStopCalculator);
break;
default:
- throw new AssertionError("Unknown break strategy: " + builder.mBreakStrategy);
+ assert false : "Unknown break strategy: " + builder.mBreakStrategy;
+ builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
+ builder.mTabStopCalculator);
}
builder.mLineBreaker.computeBreaks(recycle);
return recycle.breaks.length;
diff --git a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
index 6d3bb4ca9115..7b69388a0b1e 100644
--- a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
@@ -361,7 +361,8 @@ public class PathParser_Delegate {
}
return Arrays.copyOf(results, count);
} catch (NumberFormatException e) {
- throw new RuntimeException("error in parsing \"" + s + "\"", e);
+ assert false : "error in parsing \"" + s + "\"" + e;
+ return new float[0];
}
}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
index 27b406a70ac7..cec6bb3844db 100644
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -16,6 +16,8 @@
package android.view;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import org.xmlpull.v1.XmlPullParser;
@@ -104,8 +106,10 @@ public class LayoutInflater_Delegate {
if (layout == 0) {
final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
if (value == null || value.length() <= 0) {
- throw new InflateException("You must specify a layout in the"
- + " include tag: <include layout=\"@layout/layoutID\" />");
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
+ + " include tag: <include layout=\"@layout/layoutID\" />", null);
+ LayoutInflater.consumeChildElements(parser);
+ return;
}
// Attempt to resolve the "?attr/name" string to an identifier.
@@ -125,11 +129,11 @@ public class LayoutInflater_Delegate {
if (layout == 0) {
final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
if (value == null) {
- throw new InflateException("You must specifiy a layout in the"
- + " include tag: <include layout=\"@layout/layoutID\" />");
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
+ + " include tag: <include layout=\"@layout/layoutID\" />", null);
} else {
- throw new InflateException("You must specifiy a valid layout "
- + "reference. The layout ID " + value + " is not valid.");
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout "
+ + "reference. The layout ID " + value + " is not valid.", null);
}
} else {
final XmlResourceParser childParser =
@@ -144,8 +148,11 @@ public class LayoutInflater_Delegate {
}
if (type != XmlPullParser.START_TAG) {
- throw new InflateException(childParser.getPositionDescription() +
- ": No start tag found!");
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+ childParser.getPositionDescription() + ": No start tag found!",
+ null);
+ LayoutInflater.consumeChildElements(parser);
+ return;
}
final String childName = childParser.getName();
@@ -219,7 +226,9 @@ public class LayoutInflater_Delegate {
}
}
} else {
- throw new InflateException("<include /> can only be used inside of a ViewGroup");
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+ "<include /> can only be used inside of a ViewGroup",
+ null);
}
LayoutInflater.consumeChildElements(parser);
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
index e4b20206ef40..8ae212cd2ebf 100644
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
@@ -37,7 +37,8 @@ public class RectShadowPainter {
@NonNull Canvas canvas) {
Rect outline = new Rect();
if (!viewOutline.getRect(outline)) {
- throw new IllegalArgumentException("Outline is not a rect shadow");
+ assert false : "Outline is not a rect shadow";
+ return;
}
Rect originCanvasRect = canvas.getClipBounds();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 2e149748636b..93fd005ebc05 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -52,7 +52,6 @@ import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
-import java.util.Comparator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
@@ -62,7 +61,6 @@ import java.util.concurrent.locks.ReentrantLock;
import libcore.io.MemoryMappedFile_Delegate;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
/**
* Main entry point of the LayoutLib Bridge.
@@ -90,19 +88,14 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
/**
* Maps from id to resource type/name. This is for com.android.internal.R
*/
- private final static Map<Integer, Pair<ResourceType, String>> sRMap =
- new HashMap<Integer, Pair<ResourceType, String>>();
+ @SuppressWarnings("deprecation")
+ private final static Map<Integer, Pair<ResourceType, String>> sRMap = new HashMap<>();
/**
- * Same as sRMap except for int[] instead of int resources. This is for android.R only.
- */
- private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(384);
- /**
* Reverse map compared to sRMap, resource type -> (resource name -> id).
* This is for com.android.internal.R.
*/
- private final static Map<ResourceType, Map<String, Integer>> sRevRMap =
- new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
+ private final static Map<ResourceType, Map<String, Integer>> sRevRMap = new EnumMap<>(ResourceType.class);
// framework resources are defined as 0x01XX#### where XX is the resource type (layout,
// drawable, etc...). Using FF as the type allows for 255 resource types before we get a
@@ -111,56 +104,19 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
- new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
+ new HashMap<>();
private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
- new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
- private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
- new HashMap<String, SoftReference<Bitmap>>();
+ new HashMap<>();
+
+ private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache = new HashMap<>();
private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
- new HashMap<String, SoftReference<NinePatchChunk>>();
+ new HashMap<>();
private static Map<String, Map<String, Integer>> sEnumValueMap;
private static Map<String, String> sPlatformProperties;
/**
- * int[] wrapper to use as keys in maps.
- */
- private final static class IntArray {
- private int[] mArray;
-
- private IntArray() {
- // do nothing
- }
-
- private IntArray(int[] a) {
- mArray = a;
- }
-
- private void set(int[] a) {
- mArray = a;
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(mArray);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
-
- IntArray other = (IntArray) obj;
- return Arrays.equals(mArray, other.mArray);
- }
- }
-
- /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */
- private final static IntArray sIntArrayWrapper = new IntArray();
-
- /**
* A default log than prints to stdout/stderr.
*/
private final static LayoutLog sDefaultLog = new LayoutLog() {
@@ -192,6 +148,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
}
+ @SuppressWarnings("deprecation")
@Override
@Deprecated
public EnumSet<Capability> getCapabilities() {
@@ -272,11 +229,11 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
case STRING:
case STYLE:
// Slightly less than thousand entries in each.
- fullMap = new HashMap<String, Integer>(1280);
+ fullMap = new HashMap<>(1280);
// no break.
default:
if (fullMap == null) {
- fullMap = new HashMap<String, Integer>();
+ fullMap = new HashMap<>();
}
sRevRMap.put(resType, fullMap);
}
@@ -288,13 +245,9 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
continue;
}
Class<?> type = f.getType();
- if (type.isArray()) {
- // if the object is an int[] we put it in sRArrayMap using an IntArray
- // wrapper that properly implements equals and hashcode for the array
- // objects, as required by the map contract.
- sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
- } else {
+ if (!type.isArray()) {
Integer value = (Integer) f.get(null);
+ //noinspection deprecation
sRMap.put(value, Pair.of(resType, f.getName()));
fullMap.put(f.getName(), value);
}
@@ -332,32 +285,29 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
// values, we try and find them from the styleables.
// There were 1500 elements in this map at M timeframe.
- Map<String, Integer> revRAttrMap = new HashMap<String, Integer>(2048);
+ Map<String, Integer> revRAttrMap = new HashMap<>(2048);
sRevRMap.put(ResourceType.ATTR, revRAttrMap);
// There were 2000 elements in this map at M timeframe.
- Map<String, Integer> revRStyleableMap = new HashMap<String, Integer>(3072);
+ Map<String, Integer> revRStyleableMap = new HashMap<>(3072);
sRevRMap.put(ResourceType.STYLEABLE, revRStyleableMap);
Class<?> c = com.android.internal.R.styleable.class;
Field[] fields = c.getDeclaredFields();
// Sort the fields to bring all arrays to the beginning, so that indices into the array are
// able to refer back to the arrays (i.e. no forward references).
- Arrays.sort(fields, new Comparator<Field>() {
- @Override
- public int compare(Field o1, Field o2) {
- if (o1 == o2) {
- return 0;
- }
- Class<?> t1 = o1.getType();
- Class<?> t2 = o2.getType();
- if (t1.isArray() && !t2.isArray()) {
- return -1;
- } else if (t2.isArray() && !t1.isArray()) {
- return 1;
- }
- return o1.getName().compareTo(o2.getName());
+ Arrays.sort(fields, (o1, o2) -> {
+ if (o1 == o2) {
+ return 0;
}
+ Class<?> t1 = o1.getType();
+ Class<?> t2 = o2.getType();
+ if (t1.isArray() && !t2.isArray()) {
+ return -1;
+ } else if (t2.isArray() && !t1.isArray()) {
+ return 1;
+ }
+ return o1.getName().compareTo(o2.getName());
});
- Map<String, int[]> styleables = new HashMap<String, int[]>();
+ Map<String, int[]> styleables = new HashMap<>();
for (Field field : fields) {
if (!isValidRField(field)) {
// Only consider public static fields that are int or int[].
@@ -367,7 +317,6 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
String name = field.getName();
if (field.getType().isArray()) {
int[] styleableValue = (int[]) field.get(null);
- sRArrayMap.put(new IntArray(styleableValue), name);
styleables.put(name, styleableValue);
continue;
}
@@ -389,9 +338,11 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
if (arrayValue != null) {
String attrName = name.substring(arrayName.length() + 1);
int attrValue = arrayValue[index];
+ //noinspection deprecation
sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName));
revRAttrMap.put(attrName, attrValue);
}
+ //noinspection deprecation
sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name));
revRStyleableMap.put(name, index);
}
@@ -422,7 +373,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
@Override
public RenderSession createSession(SessionParams params) {
try {
- Result lastResult = SUCCESS.createResult();
+ Result lastResult;
RenderSessionImpl scene = new RenderSessionImpl(params);
try {
prepareThread();
@@ -456,7 +407,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
@Override
public Result renderDrawable(DrawableParams params) {
try {
- Result lastResult = SUCCESS.createResult();
+ Result lastResult;
RenderDrawable action = new RenderDrawable(params);
try {
prepareThread();
@@ -581,26 +532,16 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
* @return a Pair containing the resource type and name, or null if the id
* does not match any resource.
*/
+ @SuppressWarnings("deprecation")
public static Pair<ResourceType, String> resolveResourceId(int value) {
Pair<ResourceType, String> pair = sRMap.get(value);
if (pair == null) {
pair = sDynamicIds.resolveId(value);
- if (pair == null) {
- //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
- }
}
return pair;
}
/**
- * Returns the name of a framework resource whose value is an int array.
- */
- public static String resolveResourceId(int[] array) {
- sIntArrayWrapper.set(array);
- return sRArrayMap.get(sIntArrayWrapper);
- }
-
- /**
* Returns the integer id of a framework resource, from a given resource type and resource name.
* <p/>
* If no resource is found, it creates a dynamic id for the resource.
@@ -674,16 +615,12 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
*/
public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
if (projectKey != null) {
- Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-
- if (map == null) {
- map = new HashMap<String, SoftReference<Bitmap>>();
- sProjectBitmapCache.put(projectKey, map);
- }
+ Map<String, SoftReference<Bitmap>> map =
+ sProjectBitmapCache.computeIfAbsent(projectKey, k -> new HashMap<>());
- map.put(value, new SoftReference<Bitmap>(bmp));
+ map.put(value, new SoftReference<>(bmp));
} else {
- sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp));
+ sFrameworkBitmapCache.put(value, new SoftReference<>(bmp));
}
}
@@ -722,16 +659,12 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
*/
public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
if (projectKey != null) {
- Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
- if (map == null) {
- map = new HashMap<String, SoftReference<NinePatchChunk>>();
- sProject9PatchCache.put(projectKey, map);
- }
+ Map<String, SoftReference<NinePatchChunk>> map =
+ sProject9PatchCache.computeIfAbsent(projectKey, k -> new HashMap<>());
- map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
+ map.put(value, new SoftReference<>(ninePatch));
} else {
- sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
+ sFramework9PatchCache.put(value, new SoftReference<>(ninePatch));
}
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index 4ffb2e2bba9d..fdf6d63b1cb2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -26,10 +26,13 @@ import com.android.layoutlib.bridge.impl.RenderSessionImpl;
import com.android.tools.layoutlib.java.System_Delegate;
import com.android.util.PropertiesMap;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import java.awt.image.BufferedImage;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -42,7 +45,9 @@ import java.util.Map;
*/
public class BridgeRenderSession extends RenderSession {
+ @Nullable
private final RenderSessionImpl mSession;
+ @NonNull
private Result mLastResult;
@Override
@@ -52,41 +57,44 @@ public class BridgeRenderSession extends RenderSession {
@Override
public BufferedImage getImage() {
- return mSession.getImage();
+ return mSession != null ? mSession.getImage() :
+ new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
}
@Override
public boolean isAlphaChannelImage() {
- return mSession.isAlphaChannelImage();
+ return mSession != null && mSession.isAlphaChannelImage();
}
@Override
public List<ViewInfo> getRootViews() {
- return mSession.getViewInfos();
+ return mSession != null ? mSession.getViewInfos() : Collections.emptyList();
}
@Override
public List<ViewInfo> getSystemRootViews() {
- return mSession.getSystemViewInfos();
+ return mSession != null ? mSession.getSystemViewInfos() : Collections.emptyList();
}
@Override
public Map<Object, PropertiesMap> getDefaultProperties() {
- return mSession.getDefaultProperties();
+ return mSession != null ? mSession.getDefaultProperties() : Collections.emptyMap();
}
@Override
public Result measure(long timeout) {
- try {
- Bridge.prepareThread();
- mLastResult = mSession.acquire(timeout);
- if (mLastResult.isSuccess()) {
- mSession.invalidateRenderingSize();
- mLastResult = mSession.measure();
+ if (mSession != null) {
+ try {
+ Bridge.prepareThread();
+ mLastResult = mSession.acquire(timeout);
+ if (mLastResult.isSuccess()) {
+ mSession.invalidateRenderingSize();
+ mLastResult = mSession.measure();
+ }
+ } finally {
+ mSession.release();
+ Bridge.cleanupThread();
}
- } finally {
- mSession.release();
- Bridge.cleanupThread();
}
return mLastResult;
@@ -94,18 +102,20 @@ public class BridgeRenderSession extends RenderSession {
@Override
public Result render(long timeout, boolean forceMeasure) {
- try {
- Bridge.prepareThread();
- mLastResult = mSession.acquire(timeout);
- if (mLastResult.isSuccess()) {
- if (forceMeasure) {
- mSession.invalidateRenderingSize();
+ if (mSession != null) {
+ try {
+ Bridge.prepareThread();
+ mLastResult = mSession.acquire(timeout);
+ if (mLastResult.isSuccess()) {
+ if (forceMeasure) {
+ mSession.invalidateRenderingSize();
+ }
+ mLastResult = mSession.render(false /*freshRender*/);
}
- mLastResult = mSession.render(false /*freshRender*/);
+ } finally {
+ mSession.release();
+ Bridge.cleanupThread();
}
- } finally {
- mSession.release();
- Bridge.cleanupThread();
}
return mLastResult;
@@ -114,16 +124,18 @@ public class BridgeRenderSession extends RenderSession {
@Override
public Result animate(Object targetObject, String animationName,
boolean isFrameworkAnimation, IAnimationListener listener) {
- try {
- Bridge.prepareThread();
- mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
- if (mLastResult.isSuccess()) {
- mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
- listener);
+ if (mSession != null) {
+ try {
+ Bridge.prepareThread();
+ mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+ if (mLastResult.isSuccess()) {
+ mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
+ listener);
+ }
+ } finally {
+ mSession.release();
+ Bridge.cleanupThread();
}
- } finally {
- mSession.release();
- Bridge.cleanupThread();
}
return mLastResult;
@@ -136,16 +148,18 @@ public class BridgeRenderSession extends RenderSession {
throw new IllegalArgumentException("parentView is not a ViewGroup");
}
- try {
- Bridge.prepareThread();
- mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
- if (mLastResult.isSuccess()) {
- mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index,
- listener);
+ if (mSession != null) {
+ try {
+ Bridge.prepareThread();
+ mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+ if (mLastResult.isSuccess()) {
+ mLastResult =
+ mSession.insertChild((ViewGroup) parentView, childXml, index, listener);
+ }
+ } finally {
+ mSession.release();
+ Bridge.cleanupThread();
}
- } finally {
- mSession.release();
- Bridge.cleanupThread();
}
return mLastResult;
@@ -162,16 +176,18 @@ public class BridgeRenderSession extends RenderSession {
throw new IllegalArgumentException("childView is not a View");
}
- try {
- Bridge.prepareThread();
- mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
- if (mLastResult.isSuccess()) {
- mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
- layoutParams, listener);
+ if (mSession != null) {
+ try {
+ Bridge.prepareThread();
+ mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+ if (mLastResult.isSuccess()) {
+ mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
+ layoutParams, listener);
+ }
+ } finally {
+ mSession.release();
+ Bridge.cleanupThread();
}
- } finally {
- mSession.release();
- Bridge.cleanupThread();
}
return mLastResult;
@@ -183,15 +199,17 @@ public class BridgeRenderSession extends RenderSession {
throw new IllegalArgumentException("childView is not a View");
}
- try {
- Bridge.prepareThread();
- mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
- if (mLastResult.isSuccess()) {
- mLastResult = mSession.removeChild((View) childView, listener);
+ if (mSession != null) {
+ try {
+ Bridge.prepareThread();
+ mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+ if (mLastResult.isSuccess()) {
+ mLastResult = mSession.removeChild((View) childView, listener);
+ }
+ } finally {
+ mSession.release();
+ Bridge.cleanupThread();
}
- } finally {
- mSession.release();
- Bridge.cleanupThread();
}
return mLastResult;
@@ -221,7 +239,7 @@ public class BridgeRenderSession extends RenderSession {
}
}
- /*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) {
+ /*package*/ BridgeRenderSession(@Nullable RenderSessionImpl scene, @NonNull Result lastResult) {
mSession = scene;
if (scene != null) {
mSession.setScene(this);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 432fddaad3a4..23e049881a03 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -31,7 +31,6 @@ import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.Stack;
import com.android.resources.ResourceType;
-import com.android.resources.ResourceUrl;
import com.android.util.Pair;
import com.android.util.PropertiesMap;
import com.android.util.PropertiesMap.Property;
@@ -87,6 +86,7 @@ import android.util.TypedValue;
import android.view.BridgeInflater;
import android.view.Display;
import android.view.DisplayAdjustments;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -107,7 +107,6 @@ import java.util.List;
import java.util.Map;
import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static com.android.SdkConstants.ANDROID_NS_NAME;
import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
/**
@@ -122,23 +121,20 @@ public class BridgeContext extends Context {
static {
FRAMEWORK_PATCHED_VALUES.put("animateFirstView", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.BOOL, "animateFirstView"),
- "false"));
- FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.BOOL, "animateLayoutChanges"),
- "false"));
+ ResourceType.BOOL, "animateFirstView", "false", false));
+ FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges",
+ new ResourceValue(ResourceType.BOOL, "animateLayoutChanges", "false", false));
- FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.LAYOUT,
- "textEditSuggestionItemLayout"), "text_edit_suggestion_item"));
- FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.LAYOUT,
- "textEditSuggestionContainerLayout"), "text_edit_suggestion_container"));
- FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.STYLE,
- "textEditSuggestionHighlightStyle"),
- "TextAppearance.Holo.SuggestionHighlight"));
+ FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout",
+ new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionItemLayout",
+ "text_edit_suggestion_item", true));
+ FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout",
+ new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionContainerLayout",
+ "text_edit_suggestion_container", true));
+ FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle",
+ new ResourceValue(ResourceType.STYLE, "textEditSuggestionHighlightStyle",
+ "TextAppearance.Holo.SuggestionHighlight", true));
}
@@ -648,7 +644,12 @@ public class BridgeContext extends Context {
return null;
}
- throw new UnsupportedOperationException("Unsupported Service: " + service);
+ if (AUDIO_SERVICE.equals(service)) {
+ return null;
+ }
+
+ assert false : "Unsupported Service: " + service;
+ return null;
}
@Override
@@ -678,7 +679,9 @@ public class BridgeContext extends Context {
}
if (style == null) {
- throw new Resources.NotFoundException();
+ Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+ "Failed to find style with " + resId, null);
+ return null;
}
}
@@ -967,9 +970,7 @@ public class BridgeContext extends Context {
// there is a value in the XML, but we need to resolve it in case it's
// referencing another resource or a theme value.
ta.bridgeSetValue(index, attrName, frameworkAttr,
- mRenderResources.resolveResValue(new ResourceValue(
- ResourceUrl.create(ResourceType.STRING, attrName,
- isPlatformFile), value)));
+ mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
}
}
}
@@ -1846,6 +1847,18 @@ public class BridgeContext extends Context {
}
@Override
+ public ComponentName startForegroundService(Intent service) {
+ // pass
+ return null;
+ }
+
+ @Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ // pass
+ return null;
+ }
+
+ @Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
// pass
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 906ebb1fe39e..5a239e1f3f38 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -49,6 +49,7 @@ import android.content.pm.VersionedPackage;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
@@ -307,7 +308,8 @@ public class BridgePackageManager extends PackageManager {
@Override
public Drawable getInstantAppIcon(String packageName) {
- throw new UnsupportedOperationException();
+ assert false : "Unsupported operation";
+ return new ColorDrawable();
}
@Override
@@ -916,4 +918,9 @@ public class BridgePackageManager extends PackageManager {
public boolean canRequestPackageInstalls() {
return false;
}
+
+ @Override
+ public ComponentName getInstantAppResolverSettingsComponent() {
+ return null;
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
index f900b451fa6e..a439e7d034df 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -21,6 +21,7 @@ import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.MockView;
import com.android.layoutlib.bridge.android.BridgeContext;
import android.annotation.NonNull;
@@ -53,35 +54,41 @@ public abstract class BridgeActionBar {
mParams = params;
mCallback = params.getLayoutlibCallback().getActionBarCallback();
ResourceValue layoutName = getLayoutResource(context);
+
+ int layoutId = 0;
if (layoutName == null) {
- throw new RuntimeException("Unable to find the layout for Action Bar.");
+ assert false : "Unable to find the layout for Action Bar.";
}
- int layoutId;
- if (layoutName.isFramework()) {
- layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
- layoutName.getName(), 0);
- } else {
- layoutId = context.getProjectResourceValue(layoutName.getResourceType(),
- layoutName.getName(), 0);
-
+ else {
+ if (layoutName.isFramework()) {
+ layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
+ layoutName.getName(), 0);
+ } else {
+ layoutId = context.getProjectResourceValue(layoutName.getResourceType(),
+ layoutName.getName(), 0);
+
+ }
}
if (layoutId == 0) {
- throw new RuntimeException(
- String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
- layoutName.getName(), layoutName.getResourceType()));
- }
- if (mCallback.isOverflowPopupNeeded()) {
- // Create a RelativeLayout around the action bar, to which the overflow popup may be
- // added.
- mEnclosingLayout = new RelativeLayout(mBridgeContext);
- setMatchParent(mEnclosingLayout);
- } else {
+ assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
+ layoutName.getName(), layoutName.getResourceType());
+ mDecorContent = new MockView(context);
mEnclosingLayout = null;
}
-
- // Inflate action bar layout.
- mDecorContent =
- getInflater(context).inflate(layoutId, mEnclosingLayout, mEnclosingLayout != null);
+ else {
+ if (mCallback.isOverflowPopupNeeded()) {
+ // Create a RelativeLayout around the action bar, to which the overflow popup may be
+ // added.
+ mEnclosingLayout = new RelativeLayout(mBridgeContext);
+ setMatchParent(mEnclosingLayout);
+ } else {
+ mEnclosingLayout = null;
+ }
+
+ // Inflate action bar layout.
+ mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout,
+ mEnclosingLayout != null);
+ }
}
/**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 8bb2c593f7a1..2984fc0e5abb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -83,18 +83,18 @@ abstract class CustomBar extends LinearLayout {
XmlPullParser parser;
try {
parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name);
+
+ BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false);
+
+ try {
+ inflater.inflate(bridgeParser, this, true);
+ } finally {
+ bridgeParser.ensurePopped();
+ }
} catch (XmlPullParserException e) {
// Should not happen as the resource is bundled with the jar, and ParserFactory should
// have been initialized.
- throw new AssertionError(e);
- }
-
- BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false);
-
- try {
- inflater.inflate(bridgeParser, this, true);
- } finally {
- bridgeParser.ensurePopped();
+ assert false;
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
index d2a5117cf866..fd49c7700ea9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
@@ -176,7 +176,8 @@ public class FrameworkActionBar extends BridgeActionBar {
ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems();
ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter();
if (presenter == null) {
- throw new RuntimeException("Failed to create a Presenter for Action Bar Menus.");
+ assert false : "Failed to create a Presenter for Action Bar Menus.";
+ return false;
}
if (presenter.isOverflowReserved() &&
menus != null) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 45337742998f..75f9ec527e63 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -43,6 +43,7 @@ import android.content.res.GradientColor;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
+import android.graphics.Color;
import android.graphics.NinePatch_Delegate;
import android.graphics.Rect;
import android.graphics.Typeface;
@@ -184,7 +185,8 @@ public final class ResourceHelper {
}
if (type != XmlPullParser.START_TAG) {
- throw new XmlPullParserException("No start tag found");
+ assert false : "No start tag found";
+ return null;
}
final String name = blockParser.getName();
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
new file mode 100644
index 000000000000..63b9b436cffd
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge;
+
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.Result.Status;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class BridgeRenderSessionTest {
+ @Test
+ public void testNullSession() {
+ BridgeRenderSession renderSession = new BridgeRenderSession(null, Status.ERROR_UNKNOWN
+ .createResult("Test result"));
+
+ assertNotNull(renderSession.getImage());
+ assertNotNull(renderSession.getRootViews());
+ assertNotNull(renderSession.getSystemRootViews());
+ assertNotNull(renderSession.getDefaultProperties());
+ }
+} \ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index c83d2e4ecea3..eb264d655a9c 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -16,6 +16,7 @@
package com.android.layoutlib.bridge.intensive;
+import com.android.layoutlib.bridge.BridgeRenderSessionTest;
import com.android.layoutlib.bridge.TestDelegates;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest;
import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest;
@@ -34,7 +35,8 @@ import android.util.BridgeXmlPullAttributesTest;
@SuiteClasses({
RenderTests.class, LayoutParserWrapperTest.class,
BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class,
- Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class
+ Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class,
+ BridgeRenderSessionTest.class
})
public class Main {
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
index 00dddeed3e8c..8739b7fade9a 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
@@ -311,7 +311,6 @@ public class RenderTestBase {
sFrameworkRepo = null;
sProjectResources = null;
sLogger = null;
- sBridge.dispose();
sBridge = null;
TestUtils.gc();
@@ -329,7 +328,6 @@ public class RenderTestBase {
RenderSession session = sBridge.createSession(params);
try {
-
if (frameTimeNanos != -1) {
session.setElapsedFrameTimeNanos(frameTimeNanos);
}
@@ -338,11 +336,13 @@ public class RenderTestBase {
getLogger().error(session.getResult().getException(),
session.getResult().getErrorMessage());
}
- // Render the session with a timeout of 50s.
- Result renderResult = session.render(50000);
- if (!renderResult.isSuccess()) {
- getLogger().error(session.getResult().getException(),
- session.getResult().getErrorMessage());
+ else {
+ // Render the session with a timeout of 50s.
+ Result renderResult = session.render(50000);
+ if (!renderResult.isSuccess()) {
+ getLogger().error(session.getResult().getException(),
+ session.getResult().getErrorMessage());
+ }
}
return RenderResult.getFromSession(session);
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 10ffd8ae1f7d..1852feb8afc9 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -81,8 +81,6 @@ interface IWifiManager
boolean disableNetwork(int netId);
- boolean pingSupplicant();
-
void startScan(in ScanSettings requested, in WorkSource ws);
List<ScanResult> getScanResults(String callingPackage);
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index da9aa06918c1..afee290cbd5b 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -336,12 +336,12 @@ public class ScanResult implements Parcelable {
/**
* Indicates venue name (such as 'San Francisco Airport') published by access point; only
- * available on passpoint network and if published by access point.
+ * available on Passpoint network and if published by access point.
*/
public CharSequence venueName;
/**
- * Indicates passpoint operator name published by access point.
+ * Indicates Passpoint operator name published by access point.
*/
public CharSequence operatorFriendlyName;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 04f9059fb544..7defa7c17d95 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -367,12 +367,12 @@ public class WifiConfiguration implements Parcelable {
public WifiEnterpriseConfig enterpriseConfig;
/**
- * Fully qualified domain name of a passpoint configuration
+ * Fully qualified domain name of a Passpoint configuration
*/
public String FQDN;
/**
- * Name of passpoint credential provider
+ * Name of Passpoint credential provider
*/
public String providerFriendlyName;
@@ -385,8 +385,8 @@ public class WifiConfiguration implements Parcelable {
public boolean isHomeProviderNetwork;
/**
- * Roaming Consortium Id list for passpoint credential; identifies a set of networks where
- * passpoint credential will be considered valid
+ * Roaming Consortium Id list for Passpoint credential; identifies a set of networks where
+ * Passpoint credential will be considered valid
*/
public long[] roamingConsortiumIds;
@@ -1425,7 +1425,7 @@ public class WifiConfiguration implements Parcelable {
}
/**
- * Identify if this configuration represents a passpoint network
+ * Identify if this configuration represents a Passpoint network
*/
public boolean isPasspoint() {
return !TextUtils.isEmpty(FQDN)
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 4268f24a0999..18f30f834bc1 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -940,8 +940,8 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
- * Set realm for passpoint credential; realm identifies a set of networks where your
- * passpoint credential can be used
+ * Set realm for Passpoint credential; realm identifies a set of networks where your
+ * Passpoint credential can be used
* @param realm the realm
*/
public void setRealm(String realm) {
@@ -949,7 +949,7 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
- * Get realm for passpoint credential; see {@link #setRealm(String)} for more information
+ * Get realm for Passpoint credential; see {@link #setRealm(String)} for more information
* @return the realm
*/
public String getRealm() {
@@ -957,7 +957,7 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
- * Set plmn (Public Land Mobile Network) of the provider of passpoint credential
+ * Set plmn (Public Land Mobile Network) of the provider of Passpoint credential
* @param plmn the plmn value derived from mcc (mobile country code) & mnc (mobile network code)
*/
public void setPlmn(String plmn) {
@@ -965,7 +965,7 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
- * Get plmn (Public Land Mobile Network) for passpoint credential; see {@link #setPlmn
+ * Get plmn (Public Land Mobile Network) for Passpoint credential; see {@link #setPlmn
* (String)} for more information
* @return the plmn
*/
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ae6a6793dc9d..9ee772a61ed5 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -858,6 +858,10 @@ public class WifiManager {
/**
* Returns a WifiConfiguration matching this ScanResult
+ *
+ * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
+ * on the device.
+ *
* @param scanResult scanResult that represents the BSSID
* @return {@link WifiConfiguration} that matches this BSSID or null
* @hide
@@ -944,6 +948,8 @@ public class WifiManager {
* FQDN, the new configuration will replace the existing configuration.
*
* An {@link IllegalArgumentException} will be thrown on failure.
+ * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
+ * on the device.
*
* @param config The Passpoint configuration to be added
*/
@@ -961,8 +967,10 @@ public class WifiManager {
* Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
*
* An {@link IllegalArgumentException} will be thrown on failure.
+ * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
+ * on the device.
*
- * @param fqdn The FQDN of the passpoint configuration to be removed
+ * @param fqdn The FQDN of the Passpoint configuration to be removed
*/
public void removePasspointConfiguration(String fqdn) {
try {
@@ -979,6 +987,9 @@ public class WifiManager {
*
* An empty list will be returned when no configurations are installed.
*
+ * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
+ * on the device.
+ *
* @return A list of {@link PasspointConfiguration}
*/
public List<PasspointConfiguration> getPasspointConfigurations() {
@@ -995,6 +1006,9 @@ public class WifiManager {
* {@link #EXTRA_ICON} will indicate the result of the request.
* A missing intent extra {@link #EXTRA_ICON} will indicate a failure.
*
+ * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
+ * on the device.
+ *
* @param bssid The BSSID of the AP
* @param fileName Name of the icon file (remote file) to query from the AP
*/
@@ -1254,7 +1268,7 @@ public class WifiManager {
}
/**
- * @return true if this adapter supports passpoint
+ * @return true if this adapter supports Passpoint
* @hide
*/
public boolean isPasspointSupported() {
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 5847f798712d..40e34b1f3001 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -934,46 +934,13 @@ public class WifiScanner {
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(rssiSampleSize);
- dest.writeInt(lostApSampleSize);
- dest.writeInt(unchangedSampleSize);
- dest.writeInt(minApsBreachingThreshold);
- dest.writeInt(periodInMs);
- if (bssidInfos != null) {
- dest.writeInt(bssidInfos.length);
- for (int i = 0; i < bssidInfos.length; i++) {
- BssidInfo info = bssidInfos[i];
- dest.writeString(info.bssid);
- dest.writeInt(info.low);
- dest.writeInt(info.high);
- dest.writeInt(info.frequencyHint);
- }
- } else {
- dest.writeInt(0);
- }
}
/** Implement the Parcelable interface {@hide} */
public static final Creator<WifiChangeSettings> CREATOR =
new Creator<WifiChangeSettings>() {
public WifiChangeSettings createFromParcel(Parcel in) {
- WifiChangeSettings settings = new WifiChangeSettings();
- settings.rssiSampleSize = in.readInt();
- settings.lostApSampleSize = in.readInt();
- settings.unchangedSampleSize = in.readInt();
- settings.minApsBreachingThreshold = in.readInt();
- settings.periodInMs = in.readInt();
- int len = in.readInt();
- settings.bssidInfos = new BssidInfo[len];
- for (int i = 0; i < len; i++) {
- BssidInfo info = new BssidInfo();
- info.bssid = in.readString();
- info.low = in.readInt();
- info.high = in.readInt();
- info.frequencyHint = in.readInt();
- settings.bssidInfos[i] = info;
- }
- return settings;
+ return new WifiChangeSettings();
}
public WifiChangeSettings[] newArray(int size) {
@@ -998,20 +965,10 @@ public class WifiScanner {
int unchangedSampleSize, /* samples to confirm no change */
int minApsBreachingThreshold, /* change threshold to trigger event */
int periodInMs, /* period of scan */
- BssidInfo[] bssidInfos /* signal thresholds to crosss */
+ BssidInfo[] bssidInfos /* signal thresholds to cross */
)
{
- validateChannel();
-
- WifiChangeSettings settings = new WifiChangeSettings();
- settings.rssiSampleSize = rssiSampleSize;
- settings.lostApSampleSize = lostApSampleSize;
- settings.unchangedSampleSize = unchangedSampleSize;
- settings.minApsBreachingThreshold = minApsBreachingThreshold;
- settings.periodInMs = periodInMs;
- settings.bssidInfos = bssidInfos;
-
- configureWifiChange(settings);
+ throw new UnsupportedOperationException();
}
/**
@@ -1034,11 +991,7 @@ public class WifiScanner {
* provided on {@link #stopTrackingWifiChange}
*/
public void startTrackingWifiChange(WifiChangeListener listener) {
- Preconditions.checkNotNull(listener, "listener cannot be null");
- int key = addListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- mAsyncChannel.sendMessage(CMD_START_TRACKING_CHANGE, 0, key);
+ throw new UnsupportedOperationException();
}
/**
@@ -1047,17 +1000,13 @@ public class WifiScanner {
* #stopTrackingWifiChange}
*/
public void stopTrackingWifiChange(WifiChangeListener listener) {
- int key = removeListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- mAsyncChannel.sendMessage(CMD_STOP_TRACKING_CHANGE, 0, key);
+ throw new UnsupportedOperationException();
}
/** @hide */
@SystemApi
public void configureWifiChange(WifiChangeSettings settings) {
- validateChannel();
- mAsyncChannel.sendMessage(CMD_CONFIGURE_WIFI_CHANGE, 0, 0, settings);
+ throw new UnsupportedOperationException();
}
/** interface to receive hotlist events on; use this on {@link #setHotlist} */
@@ -1085,20 +1034,6 @@ public class WifiScanner {
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(apLostThreshold);
-
- if (bssidInfos != null) {
- dest.writeInt(bssidInfos.length);
- for (int i = 0; i < bssidInfos.length; i++) {
- BssidInfo info = bssidInfos[i];
- dest.writeString(info.bssid);
- dest.writeInt(info.low);
- dest.writeInt(info.high);
- dest.writeInt(info.frequencyHint);
- }
- } else {
- dest.writeInt(0);
- }
}
/** Implement the Parcelable interface {@hide} */
@@ -1106,17 +1041,6 @@ public class WifiScanner {
new Creator<HotlistSettings>() {
public HotlistSettings createFromParcel(Parcel in) {
HotlistSettings settings = new HotlistSettings();
- settings.apLostThreshold = in.readInt();
- int n = in.readInt();
- settings.bssidInfos = new BssidInfo[n];
- for (int i = 0; i < n; i++) {
- BssidInfo info = new BssidInfo();
- info.bssid = in.readString();
- info.low = in.readInt();
- info.high = in.readInt();
- info.frequencyHint = in.readInt();
- settings.bssidInfos[i] = info;
- }
return settings;
}
@@ -1135,14 +1059,7 @@ public class WifiScanner {
*/
public void startTrackingBssids(BssidInfo[] bssidInfos,
int apLostThreshold, BssidListener listener) {
- Preconditions.checkNotNull(listener, "listener cannot be null");
- int key = addListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- HotlistSettings settings = new HotlistSettings();
- settings.bssidInfos = bssidInfos;
- settings.apLostThreshold = apLostThreshold;
- mAsyncChannel.sendMessage(CMD_SET_HOTLIST, 0, key, settings);
+ throw new UnsupportedOperationException();
}
/**
@@ -1150,11 +1067,7 @@ public class WifiScanner {
* @param listener same object provided in {@link #startTrackingBssids}
*/
public void stopTrackingBssids(BssidListener listener) {
- Preconditions.checkNotNull(listener, "listener cannot be null");
- int key = removeListener(listener);
- if (key == INVALID_KEY) return;
- validateChannel();
- mAsyncChannel.sendMessage(CMD_RESET_HOTLIST, 0, key);
+ throw new UnsupportedOperationException();
}
@@ -1177,20 +1090,10 @@ public class WifiScanner {
/** @hide */
public static final int CMD_SCAN_RESULT = BASE + 5;
/** @hide */
- public static final int CMD_SET_HOTLIST = BASE + 6;
- /** @hide */
- public static final int CMD_RESET_HOTLIST = BASE + 7;
- /** @hide */
public static final int CMD_AP_FOUND = BASE + 9;
/** @hide */
public static final int CMD_AP_LOST = BASE + 10;
/** @hide */
- public static final int CMD_START_TRACKING_CHANGE = BASE + 11;
- /** @hide */
- public static final int CMD_STOP_TRACKING_CHANGE = BASE + 12;
- /** @hide */
- public static final int CMD_CONFIGURE_WIFI_CHANGE = BASE + 13;
- /** @hide */
public static final int CMD_WIFI_CHANGE_DETECTED = BASE + 15;
/** @hide */
public static final int CMD_WIFI_CHANGES_STABILIZED = BASE + 16;
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
index 9645b1d32a34..334205b13bba 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
@@ -85,7 +85,7 @@ public class DiscoverySessionCallback {
/**
* Called when a discovery session (publish or subscribe) terminates. Termination may be due
* to user-request (either directly through {@link DiscoverySession#destroy()} or
- * application-specified expiration, e.g. {@link PublishConfig.Builder#setPublishCount(int)}
+ * application-specified expiration, e.g. {@link PublishConfig.Builder#setTtlSec(int)}
* or {@link SubscribeConfig.Builder#setTtlSec(int)}).
*/
public void onSessionTerminated() {
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index a996844883b0..1ce12f30a25e 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -75,9 +75,6 @@ public final class PublishConfig implements Parcelable {
public final int mPublishType;
/** @hide */
- public final int mPublishCount;
-
- /** @hide */
public final int mTtlSec;
/** @hide */
@@ -85,12 +82,11 @@ public final class PublishConfig implements Parcelable {
/** @hide */
public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
- int publishType, int publichCount, int ttlSec, boolean enableTerminateNotification) {
+ int publishType, int ttlSec, boolean enableTerminateNotification) {
mServiceName = serviceName;
mServiceSpecificInfo = serviceSpecificInfo;
mMatchFilter = matchFilter;
mPublishType = publishType;
- mPublishCount = publichCount;
mTtlSec = ttlSec;
mEnableTerminateNotification = enableTerminateNotification;
}
@@ -100,8 +96,8 @@ public final class PublishConfig implements Parcelable {
return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
+ ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
- mMatchFilter)).toString() + ", mPublishType=" + mPublishType + ", mPublishCount="
- + mPublishCount + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
+ mMatchFilter)).toString() + ", mPublishType=" + mPublishType
+ + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
+ mEnableTerminateNotification + "]";
}
@@ -116,7 +112,6 @@ public final class PublishConfig implements Parcelable {
dest.writeByteArray(mServiceSpecificInfo);
dest.writeByteArray(mMatchFilter);
dest.writeInt(mPublishType);
- dest.writeInt(mPublishCount);
dest.writeInt(mTtlSec);
dest.writeInt(mEnableTerminateNotification ? 1 : 0);
}
@@ -133,11 +128,10 @@ public final class PublishConfig implements Parcelable {
byte[] ssi = in.createByteArray();
byte[] matchFilter = in.createByteArray();
int publishType = in.readInt();
- int publishCount = in.readInt();
int ttlSec = in.readInt();
boolean enableTerminateNotification = in.readInt() != 0;
- return new PublishConfig(serviceName, ssi, matchFilter, publishType, publishCount,
+ return new PublishConfig(serviceName, ssi, matchFilter, publishType,
ttlSec, enableTerminateNotification);
}
};
@@ -156,7 +150,7 @@ public final class PublishConfig implements Parcelable {
return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo,
lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter)
- && mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount
+ && mPublishType == lhs.mPublishType
&& mTtlSec == lhs.mTtlSec
&& mEnableTerminateNotification == lhs.mEnableTerminateNotification;
}
@@ -169,7 +163,6 @@ public final class PublishConfig implements Parcelable {
result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
result = 31 * result + Arrays.hashCode(mMatchFilter);
result = 31 * result + mPublishType;
- result = 31 * result + mPublishCount;
result = 31 * result + mTtlSec;
result = 31 * result + (mEnableTerminateNotification ? 1 : 0);
@@ -193,9 +186,6 @@ public final class PublishConfig implements Parcelable {
if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) {
throw new IllegalArgumentException("Invalid publishType - " + mPublishType);
}
- if (mPublishCount < 0) {
- throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
- }
if (mTtlSec < 0) {
throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
}
@@ -229,7 +219,6 @@ public final class PublishConfig implements Parcelable {
private byte[] mServiceSpecificInfo;
private byte[] mMatchFilter;
private int mPublishType = PUBLISH_TYPE_UNSOLICITED;
- private int mPublishCount = 0;
private int mTtlSec = 0;
private boolean mEnableTerminateNotification = true;
@@ -317,30 +306,6 @@ public final class PublishConfig implements Parcelable {
}
/**
- * Sets the number of times an unsolicited (configured using
- * {@link PublishConfig.Builder#setPublishType(int)}) publish session
- * will be broadcast. When the count is reached an event will be
- * generated for {@link DiscoverySessionCallback#onSessionTerminated()}
- * [unless {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
- * <p>
- * Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link DiscoverySession#destroy()} is
- * called.
- *
- * @param publishCount Number of publish packets to broadcast.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setPublishCount(int publishCount) {
- if (publishCount < 0) {
- throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
- }
- mPublishCount = publishCount;
- return this;
- }
-
- /**
* Sets the time interval (in seconds) an unsolicited (
* {@link PublishConfig.Builder#setPublishType(int)}) publish session
* will be alive - broadcasting a packet. When the TTL is reached
@@ -387,7 +352,7 @@ public final class PublishConfig implements Parcelable {
*/
public PublishConfig build() {
return new PublishConfig(mServiceName, mServiceSpecificInfo, mMatchFilter, mPublishType,
- mPublishCount, mTtlSec, mEnableTerminateNotification);
+ mTtlSec, mEnableTerminateNotification);
}
}
}
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 3397c4bc2ac3..97a6a3f91e86 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -94,9 +94,6 @@ public final class SubscribeConfig implements Parcelable {
public final int mSubscribeType;
/** @hide */
- public final int mSubscribeCount;
-
- /** @hide */
public final int mTtlSec;
/** @hide */
@@ -107,13 +104,12 @@ public final class SubscribeConfig implements Parcelable {
/** @hide */
public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
- int subscribeType, int publichCount, int ttlSec, int matchStyle,
+ int subscribeType, int ttlSec, int matchStyle,
boolean enableTerminateNotification) {
mServiceName = serviceName;
mServiceSpecificInfo = serviceSpecificInfo;
mMatchFilter = matchFilter;
mSubscribeType = subscribeType;
- mSubscribeCount = publichCount;
mTtlSec = ttlSec;
mMatchStyle = matchStyle;
mEnableTerminateNotification = enableTerminateNotification;
@@ -125,7 +121,7 @@ public final class SubscribeConfig implements Parcelable {
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
+ ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
- + ", mSubscribeCount=" + mSubscribeCount + ", mTtlSec=" + mTtlSec + ", mMatchType="
+ + ", mTtlSec=" + mTtlSec + ", mMatchType="
+ mMatchStyle + ", mEnableTerminateNotification=" + mEnableTerminateNotification
+ "]";
}
@@ -141,7 +137,6 @@ public final class SubscribeConfig implements Parcelable {
dest.writeByteArray(mServiceSpecificInfo);
dest.writeByteArray(mMatchFilter);
dest.writeInt(mSubscribeType);
- dest.writeInt(mSubscribeCount);
dest.writeInt(mTtlSec);
dest.writeInt(mMatchStyle);
dest.writeInt(mEnableTerminateNotification ? 1 : 0);
@@ -159,12 +154,11 @@ public final class SubscribeConfig implements Parcelable {
byte[] ssi = in.createByteArray();
byte[] matchFilter = in.createByteArray();
int subscribeType = in.readInt();
- int subscribeCount = in.readInt();
int ttlSec = in.readInt();
int matchStyle = in.readInt();
boolean enableTerminateNotification = in.readInt() != 0;
- return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType, subscribeCount,
+ return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType,
ttlSec, matchStyle, enableTerminateNotification);
}
};
@@ -183,7 +177,7 @@ public final class SubscribeConfig implements Parcelable {
return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo,
lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter)
- && mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount
+ && mSubscribeType == lhs.mSubscribeType
&& mTtlSec == lhs.mTtlSec && mMatchStyle == lhs.mMatchStyle
&& mEnableTerminateNotification == lhs.mEnableTerminateNotification;
}
@@ -196,7 +190,6 @@ public final class SubscribeConfig implements Parcelable {
result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
result = 31 * result + Arrays.hashCode(mMatchFilter);
result = 31 * result + mSubscribeType;
- result = 31 * result + mSubscribeCount;
result = 31 * result + mTtlSec;
result = 31 * result + mMatchStyle;
result = 31 * result + (mEnableTerminateNotification ? 1 : 0);
@@ -221,9 +214,6 @@ public final class SubscribeConfig implements Parcelable {
if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) {
throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType);
}
- if (mSubscribeCount < 0) {
- throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
- }
if (mTtlSec < 0) {
throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
}
@@ -261,7 +251,6 @@ public final class SubscribeConfig implements Parcelable {
private byte[] mServiceSpecificInfo;
private byte[] mMatchFilter;
private int mSubscribeType = SUBSCRIBE_TYPE_PASSIVE;
- private int mSubscribeCount = 0;
private int mTtlSec = 0;
private int mMatchStyle = MATCH_STYLE_ALL;
private boolean mEnableTerminateNotification = true;
@@ -350,29 +339,6 @@ public final class SubscribeConfig implements Parcelable {
}
/**
- * Sets the number of times an active (
- * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
- * will broadcast. When the count is reached an event will be
- * generated for {@link DiscoverySessionCallback#onSessionTerminated()}.
- * <p>
- * Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link DiscoverySession#destroy()} is
- * called.
- *
- * @param subscribeCount Number of subscribe packets to broadcast.
- *
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setSubscribeCount(int subscribeCount) {
- if (subscribeCount < 0) {
- throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
- }
- mSubscribeCount = subscribeCount;
- return this;
- }
-
- /**
* Sets the time interval (in seconds) an active (
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
* will be alive - i.e. broadcasting a packet. When the TTL is reached
@@ -440,7 +406,7 @@ public final class SubscribeConfig implements Parcelable {
*/
public SubscribeConfig build() {
return new SubscribeConfig(mServiceName, mServiceSpecificInfo, mMatchFilter,
- mSubscribeType, mSubscribeCount, mTtlSec, mMatchStyle,
+ mSubscribeType, mTtlSec, mMatchStyle,
mEnableTerminateNotification);
}
}
diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
index a829eb933b59..e542789e01e3 100644
--- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
@@ -16,20 +16,12 @@
package android.net.wifi;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.validateMockitoUsage;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.net.wifi.WifiScanner.BssidInfo;
-import android.net.wifi.WifiScanner.BssidListener;
import android.os.Handler;
-import android.os.Message;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
@@ -37,11 +29,10 @@ import com.android.internal.util.test.BidirectionalAsyncChannelServer;
import org.junit.After;
import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+
/**
* Unit tests for {@link android.net.wifi.WifiScanner}.
*/
@@ -51,8 +42,6 @@ public class WifiScannerTest {
private Context mContext;
@Mock
private IWifiScanner mService;
- @Mock
- private BssidListener mBssidListener;
private WifiScanner mWifiScanner;
private TestLooper mLooper;
@@ -81,31 +70,4 @@ public class WifiScannerTest {
validateMockitoUsage();
}
- private void verifySetHotlistMessage(Handler handler) {
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(handler, atLeastOnce()).handleMessage(messageCaptor.capture());
- assertEquals("message.what is not CMD_SET_HOTLIST",
- WifiScanner.CMD_SET_HOTLIST,
- messageCaptor.getValue().what);
- }
-
- /**
- * Test duplicate listeners for bssid tracking.
- */
- @Test
- public void testStartTrackingBssidsDuplicateListeners() throws Exception {
- BssidInfo[] bssids = new BssidInfo[] {
- new BssidInfo()
- };
-
- // First start tracking succeeds.
- mWifiScanner.startTrackingBssids(bssids, -100, mBssidListener);
- mLooper.dispatchAll();
- verifySetHotlistMessage(mHandler);
-
- // Second start tracking should fail.
- mWifiScanner.startTrackingBssids(bssids, -100, mBssidListener);
- mLooper.dispatchAll();
- verify(mBssidListener).onFailure(eq(WifiScanner.REASON_DUPLICATE_REQEUST), anyString());
- }
}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index eceb3658d1d6..830db22929e8 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -18,11 +18,10 @@ package android.net.wifi.aware;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -140,8 +139,8 @@ public class WifiAwareManagerTest {
// (1) connect + success
mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(binder.capture(), anyString(),
- clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false));
+ inOrder.verify(mockAwareService).connect(binder.capture(), any(),
+ clientProxyCallback.capture(), isNull(), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -150,8 +149,7 @@ public class WifiAwareManagerTest {
// (2) publish - should succeed
PublishConfig publishConfig = new PublishConfig.Builder().build();
session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
- any(IWifiAwareDiscoverySessionCallback.class));
+ inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig), any());
// (3) disconnect
session.destroy();
@@ -163,8 +161,8 @@ public class WifiAwareManagerTest {
// (5) connect
mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(binder.capture(), anyString(),
- any(IWifiAwareEventCallback.class), (ConfigRequest) isNull(), eq(false));
+ inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), isNull(),
+ eq(false));
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
}
@@ -185,16 +183,16 @@ public class WifiAwareManagerTest {
// (1) connect + failure
mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ isNull(), eq(false));
clientProxyCallback.getValue().onConnectFail(reason);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttachFailed();
// (2) connect + success
mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ isNull(), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -203,8 +201,7 @@ public class WifiAwareManagerTest {
// (4) subscribe: should succeed
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig),
- any(IWifiAwareDiscoverySessionCallback.class));
+ inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig), any());
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
}
@@ -223,19 +220,19 @@ public class WifiAwareManagerTest {
// (1) connect + success
mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ isNull(), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(any(WifiAwareSession.class));
+ inOrder.verify(mockCallback).onAttached(any());
// (2) connect + success
mDut.attach(mockCallback, mMockLooperHandler);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), (ConfigRequest) isNull(), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ isNull(), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId + 1);
mMockLooper.dispatchAll();
- inOrder.verify(mockCallback).onAttached(any(WifiAwareSession.class));
+ inOrder.verify(mockCallback).onAttached(any());
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService);
}
@@ -278,8 +275,8 @@ public class WifiAwareManagerTest {
// (0) connect + success
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -370,8 +367,8 @@ public class WifiAwareManagerTest {
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -426,8 +423,8 @@ public class WifiAwareManagerTest {
// (0) connect + success
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -507,8 +504,8 @@ public class WifiAwareManagerTest {
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -691,7 +688,6 @@ public class WifiAwareManagerTest {
collector.checkThat("mServiceName", subscribeConfig.mServiceName, equalTo(null));
collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType,
equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE));
- collector.checkThat("mSubscribeCount", subscribeConfig.mSubscribeCount, equalTo(0));
collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0));
collector.checkThat("mMatchStyle", subscribeConfig.mMatchStyle,
equalTo(SubscribeConfig.MATCH_STYLE_ALL));
@@ -714,7 +710,7 @@ public class WifiAwareManagerTest {
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setSubscribeType(subscribeType)
- .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+ .setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
collector.checkThat("mServiceName", serviceName.getBytes(),
@@ -724,8 +720,6 @@ public class WifiAwareManagerTest {
collector.checkThat("mMatchFilter", matchFilter, equalTo(subscribeConfig.mMatchFilter));
collector.checkThat("mSubscribeType", subscribeType,
equalTo(subscribeConfig.mSubscribeType));
- collector.checkThat("mSubscribeCount", subscribeCount,
- equalTo(subscribeConfig.mSubscribeCount));
collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec));
collector.checkThat("mMatchStyle", matchStyle, equalTo(subscribeConfig.mMatchStyle));
collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
@@ -747,7 +741,7 @@ public class WifiAwareManagerTest {
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setSubscribeType(subscribeType)
- .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+ .setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
Parcel parcelW = Parcel.obtain();
@@ -769,11 +763,6 @@ public class WifiAwareManagerTest {
}
@Test(expected = IllegalArgumentException.class)
- public void testSubscribeConfigBuilderNegativeCount() {
- new SubscribeConfig.Builder().setSubscribeCount(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
public void testSubscribeConfigBuilderNegativeTtl() {
new SubscribeConfig.Builder().setTtlSec(-100);
}
@@ -797,7 +786,6 @@ public class WifiAwareManagerTest {
collector.checkThat("mServiceName", publishConfig.mServiceName, equalTo(null));
collector.checkThat("mPublishType", publishConfig.mPublishType,
equalTo(PublishConfig.PUBLISH_TYPE_UNSOLICITED));
- collector.checkThat("mPublishCount", publishConfig.mPublishCount, equalTo(0));
collector.checkThat("mTtlSec", publishConfig.mTtlSec, equalTo(0));
collector.checkThat("mEnableTerminateNotification",
publishConfig.mEnableTerminateNotification, equalTo(true));
@@ -817,7 +805,7 @@ public class WifiAwareManagerTest {
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setPublishType(publishType)
- .setPublishCount(publishCount).setTtlSec(publishTtl)
+ .setTtlSec(publishTtl)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
collector.checkThat("mServiceName", serviceName.getBytes(),
@@ -826,7 +814,6 @@ public class WifiAwareManagerTest {
serviceSpecificInfo.getBytes(), equalTo(publishConfig.mServiceSpecificInfo));
collector.checkThat("mMatchFilter", matchFilter, equalTo(publishConfig.mMatchFilter));
collector.checkThat("mPublishType", publishType, equalTo(publishConfig.mPublishType));
- collector.checkThat("mPublishCount", publishCount, equalTo(publishConfig.mPublishCount));
collector.checkThat("mTtlSec", publishTtl, equalTo(publishConfig.mTtlSec));
collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
equalTo(publishConfig.mEnableTerminateNotification));
@@ -846,7 +833,7 @@ public class WifiAwareManagerTest {
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setPublishType(publishType)
- .setPublishCount(publishCount).setTtlSec(publishTtl)
+ .setTtlSec(publishTtl)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
Parcel parcelW = Parcel.obtain();
@@ -868,11 +855,6 @@ public class WifiAwareManagerTest {
}
@Test(expected = IllegalArgumentException.class)
- public void testPublishConfigBuilderNegativeCount() {
- new PublishConfig.Builder().setPublishCount(-4);
- }
-
- @Test(expected = IllegalArgumentException.class)
public void testPublishConfigBuilderNegativeTtl() {
new PublishConfig.Builder().setTtlSec(-10);
}
@@ -899,8 +881,7 @@ public class WifiAwareManagerTest {
final RttManager.RttResult rttResults = new RttManager.RttResult();
rttResults.distance = 10;
- when(mockAwareService.startRanging(anyInt(), anyInt(),
- any(RttManager.ParcelableRttParams.class))).thenReturn(rangingId);
+ when(mockAwareService.startRanging(anyInt(), anyInt(), any())).thenReturn(rangingId);
InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
mockPublishSession, mockRttListener);
@@ -919,8 +900,8 @@ public class WifiAwareManagerTest {
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -994,8 +975,8 @@ public class WifiAwareManagerTest {
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
@@ -1085,8 +1066,8 @@ public class WifiAwareManagerTest {
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
- inOrder.verify(mockAwareService).connect(any(IBinder.class), anyString(),
- clientProxyCallback.capture(), eq(configRequest), eq(false));
+ inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+ eq(configRequest), eq(false));
clientProxyCallback.getValue().onConnectSuccess(clientId);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());