summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp10
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.aidl (renamed from core/proto/android/stats/devicepolicy/device_policy.proto)17
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java156
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl19
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java23
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java312
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java47
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchBatchResultCallback.aidl (renamed from core/proto/android/stats/mediaprovider/mediaprovider_enums.proto)27
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl44
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchResultCallback.aidl (renamed from core/proto/android/bluetooth/hfp/enums.proto)22
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java123
-rw-r--r--cmds/bootanimation/BootAnimation.cpp2
-rw-r--r--cmds/statsd/tests/LogEvent_test.cpp2
-rw-r--r--core/api/current.txt15
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/api/test-current.txt15
-rw-r--r--core/java/android/content/pm/SharedLibraryInfo.java9
-rw-r--r--core/java/android/hardware/input/InputManager.java18
-rw-r--r--core/java/android/inputmethodservice/IInputMethodSessionWrapper.java10
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java29
-rw-r--r--core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java9
-rw-r--r--core/java/android/net/NetworkAgent.java44
-rw-r--r--core/java/android/net/NetworkCapabilities.java5
-rw-r--r--core/java/android/net/NetworkProvider.java7
-rw-r--r--core/java/android/os/ParcelableHolder.java20
-rw-r--r--core/java/android/view/IWindowManager.aidl12
-rw-r--r--core/java/android/view/ImeFocusController.java20
-rw-r--r--core/java/android/view/InputDevice.java10
-rw-r--r--core/java/android/view/SurfaceView.java2
-rw-r--r--core/java/android/view/WindowManager.java64
-rw-r--r--core/java/android/view/WindowManagerImpl.java10
-rw-r--r--core/java/android/view/inputmethod/DumpableInputConnection.java (renamed from core/proto/android/stats/enums.proto)25
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java58
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java29
-rw-r--r--core/java/android/window/TransitionInfo.java88
-rw-r--r--core/java/com/android/internal/compat/ChangeReporter.java4
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java16
-rw-r--r--core/java/com/android/internal/view/IInputConnectionWrapper.java417
-rw-r--r--core/java/com/android/internal/view/IInputMethodClient.aidl2
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl5
-rw-r--r--core/java/com/android/internal/view/IInputMethodSession.aidl2
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java41
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java159
-rw-r--r--core/proto/Android.bp30
-rw-r--r--core/proto/android/app/enums.proto215
-rw-r--r--core/proto/android/app/job/enums.proto38
-rw-r--r--core/proto/android/app/media_output_enum.proto65
-rw-r--r--core/proto/android/app/settings_enums.proto2794
-rw-r--r--core/proto/android/app/tvsettings_enums.proto1132
-rw-r--r--core/proto/android/bluetooth/enums.proto142
-rw-r--r--core/proto/android/bluetooth/hci/enums.proto559
-rw-r--r--core/proto/android/bluetooth/smp/enums.proto58
-rw-r--r--core/proto/android/debug/enums.proto67
-rw-r--r--core/proto/android/hardware/biometrics/enums.proto60
-rw-r--r--core/proto/android/hardware/sensor/assist/enums.proto34
-rw-r--r--core/proto/android/net/networkcapabilities.proto133
-rw-r--r--core/proto/android/net/networkrequest.proto2
-rw-r--r--core/proto/android/os/batterystats.proto4
-rw-r--r--core/proto/android/os/enums.proto169
-rw-r--r--core/proto/android/os/incident.proto2
-rw-r--r--core/proto/android/server/activitymanagerservice.proto2
-rw-r--r--core/proto/android/server/bluetooth_manager_service.proto2
-rw-r--r--core/proto/android/server/connectivity/Android.bp26
-rw-r--r--core/proto/android/server/connectivity/data_stall_event.proto91
-rw-r--r--core/proto/android/server/enums.proto40
-rw-r--r--core/proto/android/server/job/enums.proto43
-rw-r--r--core/proto/android/server/jobscheduler.proto4
-rw-r--r--core/proto/android/server/location/enums.proto132
-rw-r--r--core/proto/android/server/powermanagerservice.proto6
-rw-r--r--core/proto/android/server/windowmanagerservice.proto6
-rw-r--r--core/proto/android/service/battery.proto2
-rw-r--r--core/proto/android/service/procstats.proto2
-rw-r--r--core/proto/android/service/procstats_enum.proto102
-rw-r--r--core/proto/android/service/usb.proto440
-rw-r--r--core/proto/android/stats/camera/Android.bp33
-rw-r--r--core/proto/android/stats/camera/camera.proto44
-rw-r--r--core/proto/android/stats/camera/jarjar-rules.txt1
-rw-r--r--core/proto/android/stats/connectivity/Android.bp38
-rw-r--r--core/proto/android/stats/connectivity/network_stack.proto180
-rw-r--r--core/proto/android/stats/connectivity/tethering.proto97
-rw-r--r--core/proto/android/stats/devicepolicy/Android.bp33
-rw-r--r--core/proto/android/stats/devicepolicy/device_policy_enums.proto204
-rw-r--r--core/proto/android/stats/devicepolicy/jarjar-rules.txt1
-rw-r--r--core/proto/android/stats/dnsresolver/Android.bp24
-rw-r--r--core/proto/android/stats/dnsresolver/dns_resolver.proto375
-rw-r--r--core/proto/android/stats/docsui/docsui_enums.proto197
-rw-r--r--core/proto/android/stats/hdmi/enums.proto122
-rw-r--r--core/proto/android/stats/intelligence/enums.proto40
-rw-r--r--core/proto/android/stats/launcher/Android.bp40
-rw-r--r--core/proto/android/stats/launcher/launcher.proto88
-rw-r--r--core/proto/android/stats/location/location_enums.proto122
-rw-r--r--core/proto/android/stats/mediametrics/mediametrics.proto354
-rw-r--r--core/proto/android/stats/otaupdate/updateengine_enums.proto82
-rw-r--r--core/proto/android/stats/style/Android.bp27
-rw-r--r--core/proto/android/stats/style/style_enums.proto69
-rw-r--r--core/proto/android/stats/sysui/notification_enums.proto30
-rw-r--r--core/proto/android/stats/textclassifier/Android.bp23
-rw-r--r--core/proto/android/stats/textclassifier/textclassifier_enums.proto87
-rw-r--r--core/proto/android/stats/tls/enums.proto70
-rw-r--r--core/proto/android/stats/tv/tif_enums.proto56
-rw-r--r--core/proto/android/telecomm/enums.proto203
-rw-r--r--core/proto/android/telephony/enums.proto288
-rw-r--r--core/proto/android/view/enums.proto71
-rw-r--r--core/proto/android/view/inputmethod/inputconnection.proto (renamed from core/proto/android/bluetooth/a2dp/enums.proto)31
-rw-r--r--core/proto/android/view/inputmethod/inputmethodeditortrace.proto2
-rw-r--r--core/proto/android/wifi/enums.proto112
-rw-r--r--core/tests/coretests/src/android/app/ApplicationLoadersTest.java2
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java42
-rw-r--r--core/tests/coretests/src/android/security/CredentialManagementAppTest.java185
-rw-r--r--core/tests/coretests/src/android/widget/TextViewActivityTest.java50
-rw-r--r--core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java15
-rw-r--r--data/etc/services.core.protolog.json24
-rw-r--r--keystore/java/android/security/AppUriAuthenticationPolicy.aidl (renamed from core/proto/android/stats/storage/storage_enums.proto)13
-rw-r--r--keystore/java/android/security/AppUriAuthenticationPolicy.java226
-rw-r--r--keystore/java/android/security/CredentialManagementApp.java123
-rw-r--r--keystore/java/android/security/Credentials.java2
-rw-r--r--keystore/java/android/security/KeyChain.java38
-rw-r--r--keystore/java/android/security/UrisToAliases.java138
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreProvider.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/Android.bp2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt17
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt9
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt19
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FixedAppHelper.kt (renamed from core/proto/android/stats/accessibility/accessibility_enums.proto)28
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AppTestBase.kt46
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt118
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt83
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt203
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt127
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt127
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt7
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml30
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java82
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java104
-rw-r--r--libs/hwui/DisplayListOps.in1
-rw-r--r--libs/hwui/RecordingCanvas.cpp28
-rw-r--r--libs/hwui/RecordingCanvas.h6
-rw-r--r--libs/hwui/WebViewFunctorManager.cpp63
-rw-r--r--libs/hwui/WebViewFunctorManager.h6
-rw-r--r--libs/hwui/jni/pdf/PdfEditor.cpp4
-rw-r--r--libs/hwui/private/hwui/WebViewFunctor.h45
-rw-r--r--libs/hwui/tests/common/TestUtils.h3
-rw-r--r--libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp2
-rw-r--r--libs/hwui/tests/unit/RenderNodeDrawableTests.cpp16
-rw-r--r--libs/hwui/tests/unit/SkiaDisplayListTests.cpp10
-rw-r--r--libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp4
-rw-r--r--location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java38
-rw-r--r--location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java2
-rw-r--r--native/webview/plat_support/draw_fn.h83
-rw-r--r--native/webview/plat_support/draw_functor.cpp61
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml17
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java5
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java83
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml2
-rw-r--r--packages/SystemUI/res-product/values/strings.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid_v2.xml58
-rw-r--r--packages/SystemUI/res/layout/global_actions_lock_view.xml35
-rw-r--r--packages/SystemUI/res/layout/global_actions_view.xml52
-rw-r--r--packages/SystemUI/res/values/config.xml3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java246
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java407
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java6
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java226
-rw-r--r--services/core/java/com/android/server/OWNERS3
-rw-r--r--services/core/java/com/android/server/RescueParty.java94
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java3
-rw-r--r--services/core/java/com/android/server/TEST_MAPPING4
-rw-r--r--services/core/java/com/android/server/UserspaceRebootLogger.java10
-rw-r--r--services/core/java/com/android/server/VibratorManagerService.java2
-rw-r--r--services/core/java/com/android/server/VibratorService.java1072
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java16
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java165
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecConfig.java174
-rwxr-xr-xservices/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java9
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java1
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java122
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java17
-rw-r--r--services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java6
-rw-r--r--services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java4
-rw-r--r--services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java71
-rw-r--r--services/core/java/com/android/server/rollback/Rollback.java37
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java48
-rw-r--r--services/core/java/com/android/server/rollback/RollbackStore.java41
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorService.java2
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java67
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java32
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java145
-rw-r--r--services/core/java/com/android/server/uri/TEST_MAPPING20
-rw-r--r--services/core/java/com/android/server/vibrator/InputDeviceDelegate.java171
-rw-r--r--services/core/java/com/android/server/vibrator/Vibration.java287
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationScaler.java1
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java61
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorController.java472
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java21
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java21
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java23
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java86
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettings.java34
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java19
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java5
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsController.java19
-rw-r--r--services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java74
-rw-r--r--services/core/java/com/android/server/wm/Transition.java169
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java35
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java22
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java6
-rw-r--r--services/core/jni/Android.bp2
-rw-r--r--services/core/jni/OWNERS2
-rw-r--r--services/core/jni/com_android_server_vibrator_VibratorController.cpp (renamed from services/core/jni/com_android_server_VibratorService.cpp)226
-rw-r--r--services/core/jni/onload.cpp4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java134
-rw-r--r--services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java16
-rw-r--r--services/tests/servicestests/src/com/android/server/VibratorServiceTest.java252
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java111
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java35
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java27
-rw-r--r--services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java286
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java291
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java342
-rw-r--r--services/tests/wmtests/AndroidManifest.xml2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java44
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java50
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java382
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java178
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java99
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java42
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java21
-rw-r--r--telecomm/java/android/telecom/PhoneAccount.java11
-rw-r--r--telephony/java/android/telephony/ims/RcsUceAdapter.java32
-rw-r--r--telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl2
-rw-r--r--tests/BootImageProfileTest/TEST_MAPPING7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt2
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java5
-rw-r--r--tests/net/common/java/android/net/OemNetworkPreferencesTest.java4
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java168
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java31
346 files changed, 8657 insertions, 13334 deletions
diff --git a/Android.bp b/Android.bp
index d9fe7cc59261..c47b74717dcd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -747,6 +747,7 @@ gensrcs {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -773,6 +774,7 @@ gensrcs {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -912,6 +914,7 @@ java_library_host {
name: "platformprotos",
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
":libstats_internal_protos",
"cmds/am/proto/instrumentation_data.proto",
"cmds/statsd/src/**/*.proto",
@@ -947,6 +950,7 @@ java_library {
sdk_version: "9",
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -962,6 +966,7 @@ java_library {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -983,7 +988,9 @@ cc_defaults {
proto: {
export_proto_headers: true,
- include_dirs: ["external/protobuf/src"],
+ include_dirs: [
+ "external/protobuf/src",
+ ],
},
cflags: [
@@ -994,6 +1001,7 @@ cc_defaults {
srcs: [
":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
"core/proto/**/*.proto",
],
}
diff --git a/core/proto/android/stats/devicepolicy/device_policy.proto b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.aidl
index af30cf3f9941..4686de8df268 100644
--- a/core/proto/android/stats/devicepolicy/device_policy.proto
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
+/**
+ * Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -13,12 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.app.appsearch;
-syntax = "proto2";
-
-package android.stats.devicepolicy;
-option java_multiple_files = true;
-
-message StringList {
- repeated string string_value = 1;
-}
+/** {@hide} */
+parcelable AppSearchBatchResult; \ No newline at end of file
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index f2c9942edbb3..e57359fbf50e 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -15,10 +15,12 @@
*/
package android.app.appsearch;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
import android.os.Bundle;
+import android.os.ParcelableException;
import android.os.RemoteException;
import com.android.internal.infra.AndroidFuture;
@@ -27,7 +29,10 @@ import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* This class provides access to the centralized AppSearch index maintained by the system.
@@ -40,12 +45,99 @@ import java.util.concurrent.ExecutionException;
// TODO(b/148046169): This class header needs a detailed example/tutorial.
@SystemService(Context.APP_SEARCH_SERVICE)
public class AppSearchManager {
- private static final String DEFAULT_DATABASE = "";
+ /**
+ * The default empty database name.
+ * @hide
+ */
+ public static final String DEFAULT_DATABASE_NAME = "";
+
private final IAppSearchManager mService;
/** @hide */
public AppSearchManager(@NonNull IAppSearchManager service) {
- mService = service;
+ mService = Objects.requireNonNull(service);
+ }
+
+ /** Contains information about how to create the search session. */
+ public static final class SearchContext {
+ final String mDatabaseName;
+
+ SearchContext(@NonNull String databaseName) {
+ mDatabaseName = Objects.requireNonNull(databaseName);
+ }
+
+ /**
+ * Returns the name of the database to create or open.
+ *
+ * <p>Databases with different names are fully separate with distinct types, namespaces,
+ * and data.
+ */
+ @NonNull
+ public String getDatabaseName() {
+ return mDatabaseName;
+ }
+
+ /** Builder for {@link SearchContext} objects. */
+ public static final class Builder {
+ private String mDatabaseName = DEFAULT_DATABASE_NAME;
+ private boolean mBuilt = false;
+
+ /**
+ * Sets the name of the database associated with {@link AppSearchSession}.
+ *
+ * <p>{@link AppSearchSession} will create or open a database under the given name.
+ *
+ * <p>Databases with different names are fully separate with distinct types, namespaces,
+ * and data.
+ *
+ * <p>Database name cannot contain {@code '/'}.
+ *
+ * <p>If not specified, defaults to {@link #DEFAULT_DATABASE_NAME}.
+ * @param databaseName The name of the database.
+ * @throws IllegalArgumentException if the databaseName contains {@code '/'}.
+ */
+ @NonNull
+ public Builder setDatabaseName(@NonNull String databaseName) {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ Objects.requireNonNull(databaseName);
+ if (databaseName.contains("/")) {
+ throw new IllegalArgumentException("Database name cannot contain '/'");
+ }
+ mDatabaseName = databaseName;
+ return this;
+ }
+
+ /** Builds a {@link SearchContext} instance. */
+ @NonNull
+ public SearchContext build() {
+ Preconditions.checkState(!mBuilt, "Builder has already been used");
+ mBuilt = true;
+ return new SearchContext(mDatabaseName);
+ }
+ }
+ }
+
+ /**
+ * Creates a new {@link AppSearchSession}.
+ *
+ * <p>This process requires an AppSearch native indexing file system for each user. If it's not
+ * created for this user, the initialization process will create one under user's directory.
+ *
+ * @param searchContext The {@link SearchContext} contains all information to create a new
+ * {@link AppSearchSession}
+ * @param executor Executor on which to invoke the callback.
+ * @param callback The {@link AppSearchResult}&lt;{@link AppSearchSession}&gt; of
+ * performing this operation. Or a {@link AppSearchResult} with failure
+ * reason code and error information.
+ */
+ public void createSearchSession(
+ @NonNull SearchContext searchContext,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
+ Objects.requireNonNull(searchContext);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ AppSearchSession.createSearchSession(searchContext, mService, executor, callback);
}
/**
@@ -99,7 +191,7 @@ public class AppSearchManager {
*
* @param request The schema update request.
* @return the result of performing this operation.
- *
+ * @deprecated use {@link AppSearchSession#setSchema} instead.
* @hide
*/
@NonNull
@@ -113,9 +205,14 @@ public class AppSearchManager {
}
AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
try {
- mService.setSchema(DEFAULT_DATABASE, schemaBundles, request.isForceOverride(), future);
+ mService.setSchema(DEFAULT_DATABASE_NAME, schemaBundles, request.isForceOverride(),
+ new IAppSearchResultCallback.Stub() {
+ public void onResult(AppSearchResult result) {
+ future.complete(result);
+ }
+ });
} catch (RemoteException e) {
- future.completeExceptionally(e);
+ throw e.rethrowFromSystemServer();
}
return getFutureOrThrow(future);
}
@@ -134,6 +231,9 @@ public class AppSearchManager {
* {@link AppSearchBatchResult} are the URIs of the input documents. The values are
* {@code null} if they were successfully indexed, or a failed {@link AppSearchResult}
* otherwise.
+ * @throws RuntimeException If an error occurred during the execution.
+ *
+ * @deprecated use {@link AppSearchSession#putDocuments} instead.
* @hide
*/
public AppSearchBatchResult<String, Void> putDocuments(@NonNull PutDocumentsRequest request) {
@@ -146,7 +246,16 @@ public class AppSearchManager {
}
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
try {
- mService.putDocuments(DEFAULT_DATABASE, documentBundles, future);
+ mService.putDocuments(DEFAULT_DATABASE_NAME, documentBundles,
+ new IAppSearchBatchResultCallback.Stub() {
+ public void onResult(AppSearchBatchResult result) {
+ future.complete(result);
+ }
+
+ public void onSystemError(ParcelableException exception) {
+ future.completeExceptionally(exception);
+ }
+ });
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -165,6 +274,9 @@ public class AppSearchManager {
* {@link GenericDocument}s on success, or a failed {@link AppSearchResult} otherwise.
* URIs that are not found will return a failed {@link AppSearchResult} with a result code
* of {@link AppSearchResult#RESULT_NOT_FOUND}.
+ * @throws RuntimeException If an error occurred during the execution.
+ *
+ * @deprecated use {@link AppSearchSession#getByUri} instead.
*/
public AppSearchBatchResult<String, GenericDocument> getByUri(
@NonNull GetByUriRequest request) {
@@ -173,7 +285,16 @@ public class AppSearchManager {
List<String> uris = new ArrayList<>(request.getUris());
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
try {
- mService.getDocuments(DEFAULT_DATABASE, request.getNamespace(), uris, future);
+ mService.getDocuments(DEFAULT_DATABASE_NAME, request.getNamespace(), uris,
+ new IAppSearchBatchResultCallback.Stub() {
+ public void onResult(AppSearchBatchResult result) {
+ future.complete(result);
+ }
+
+ public void onSystemError(ParcelableException exception) {
+ future.completeExceptionally(exception);
+ }
+ });
} catch (RemoteException e) {
future.completeExceptionally(e);
}
@@ -252,6 +373,9 @@ public class AppSearchManager {
*
* @param queryExpression Query String to search.
* @param searchSpec Spec for setting filters, raw query etc.
+ * @throws RuntimeException If an error occurred during the execution.
+ *
+ * @deprecated use AppSearchSession#query instead.
* @hide
*/
@NonNull
@@ -261,7 +385,7 @@ public class AppSearchManager {
// them in one big list.
AndroidFuture<AppSearchResult> searchResultsFuture = new AndroidFuture<>();
try {
- mService.query(DEFAULT_DATABASE, queryExpression,
+ mService.query(DEFAULT_DATABASE_NAME, queryExpression,
searchSpec.getBundle(), searchResultsFuture);
} catch (RemoteException e) {
searchResultsFuture.completeExceptionally(e);
@@ -278,7 +402,7 @@ public class AppSearchManager {
}
/**
- * Deletes {@link GenericDocument}s by URI.
+ * Removes {@link GenericDocument}s by URI.
*
* <p>You should not call this method directly; instead, use the {@code AppSearch#delete()} API
* provided by JetPack.
@@ -289,12 +413,24 @@ public class AppSearchManager {
* or a failed {@link AppSearchResult} otherwise. URIs that are not found will return a
* failed {@link AppSearchResult} with a result code of
* {@link AppSearchResult#RESULT_NOT_FOUND}.
+ * @throws RuntimeException If an error occurred during the execution.
+ *
+ * @deprecated use {@link AppSearchSession#removeByUri} instead.
*/
public AppSearchBatchResult<String, Void> removeByUri(@NonNull RemoveByUriRequest request) {
List<String> uris = new ArrayList<>(request.getUris());
AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
try {
- mService.removeByUri(DEFAULT_DATABASE, request.getNamespace(), uris, future);
+ mService.removeByUri(DEFAULT_DATABASE_NAME, request.getNamespace(), uris,
+ new IAppSearchBatchResultCallback.Stub() {
+ public void onResult(AppSearchBatchResult result) {
+ future.complete(result);
+ }
+
+ public void onSystemError(ParcelableException exception) {
+ future.completeExceptionally(exception);
+ }
+ });
} catch (RemoteException e) {
future.completeExceptionally(e);
}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl
new file mode 100644
index 000000000000..f0b29964b895
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.appsearch;
+
+/** {@hide} */
+parcelable AppSearchResult; \ No newline at end of file
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
index 979eab90a980..6e2ed70cca01 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
@@ -19,9 +19,11 @@ package android.app.appsearch;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.appsearch.exceptions.AppSearchException;
import android.os.Parcel;
import android.os.Parcelable;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -218,4 +220,25 @@ public final class AppSearchResult<ValueType> implements Parcelable {
@ResultCode int resultCode, @Nullable String errorMessage) {
return new AppSearchResult<>(resultCode, /*resultValue=*/ null, errorMessage);
}
+
+ /** @hide */
+ @NonNull
+ public static <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
+ @NonNull Throwable t) {
+ if (t instanceof AppSearchException) {
+ return ((AppSearchException) t).toAppSearchResult();
+ }
+
+ @AppSearchResult.ResultCode int resultCode;
+ if (t instanceof IllegalStateException) {
+ resultCode = AppSearchResult.RESULT_INTERNAL_ERROR;
+ } else if (t instanceof IllegalArgumentException) {
+ resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
+ } else if (t instanceof IOException) {
+ resultCode = AppSearchResult.RESULT_IO_ERROR;
+ } else {
+ resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
+ }
+ return AppSearchResult.newFailedResult(resultCode, t.toString());
+ }
}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
new file mode 100644
index 000000000000..531436ecaf0c
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.os.Bundle;
+import android.os.ParcelableException;
+import android.os.RemoteException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Represents a connection to an AppSearch storage system where {@link GenericDocument}s can be
+ * placed and queried.
+ * @hide
+ */
+public final class AppSearchSession {
+ private final String mDatabaseName;
+ private final IAppSearchManager mService;
+
+ static void createSearchSession(
+ @NonNull AppSearchManager.SearchContext searchContext,
+ @NonNull IAppSearchManager service,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
+ AppSearchSession searchSession =
+ new AppSearchSession(searchContext.mDatabaseName, service);
+ searchSession.initialize(executor, callback);
+ }
+
+ // NOTE: No instance of this class should be created or returned except via initialize().
+ // Once the callback.accept has been called here, the class is ready to use.
+ private void initialize(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) {
+ try {
+ mService.initialize(new IAppSearchResultCallback.Stub() {
+ public void onResult(AppSearchResult result) {
+ executor.execute(() -> {
+ if (result.isSuccess()) {
+ callback.accept(
+ AppSearchResult.newSuccessfulResult(AppSearchSession.this));
+ } else {
+ callback.accept(result);
+ }
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ private AppSearchSession(@NonNull String databaseName, @NonNull IAppSearchManager service) {
+ mDatabaseName = databaseName;
+ mService = service;
+ }
+
+ /**
+ * Sets the schema will be used by documents provided to the {@link #putDocuments} method.
+ *
+ * <p>The schema provided here is compared to the stored copy of the schema previously supplied
+ * to {@link #setSchema}, if any, to determine how to treat existing documents. The following
+ * types of schema modifications are always safe and are made without deleting any existing
+ * documents:
+ * <ul>
+ * <li>Addition of new types
+ * <li>Addition of new
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED} properties to a
+ * type
+ * <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED} property.
+ * </ul>
+ *
+ * <p>The following types of schema changes are not backwards-compatible:
+ * <ul>
+ * <li>Removal of an existing type
+ * <li>Removal of a property from a type
+ * <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
+ * <li>For properties of {@code Document} type, changing the schema type of
+ * {@code Document}s of that property
+ * <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property).
+ * <li>Adding a
+ * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property.
+ * </ul>
+ * <p>Supplying a schema with such changes will, by default, result in this call returning an
+ * {@link AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an
+ * error message describing the incompatibility. In this case the previously set schema will
+ * remain active.
+ *
+ * <p>If you need to make non-backwards-compatible changes as described above, you can set the
+ * {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In this case,
+ * instead of returning an {@link AppSearchResult} with the
+ * {@link AppSearchResult#RESULT_INVALID_SCHEMA} error code, all documents which are not
+ * compatible with the new schema will be deleted and the incompatible schema will be applied.
+ *
+ * <p>It is a no-op to set the same schema as has been previously set; this is handled
+ * efficiently.
+ *
+ * @param request The schema update request.
+ * @param executor Executor on which to invoke the callback.
+ * @param callback Callback to receive errors resulting from setting the schema. If the
+ * operation succeeds, the callback will be invoked with {@code null}.
+ */
+ public void setSchema(
+ @NonNull SetSchemaRequest request,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<Void>> callback) {
+ Objects.requireNonNull(request);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size());
+ for (AppSearchSchema schema : request.getSchemas()) {
+ schemaBundles.add(schema.getBundle());
+ }
+ try {
+ mService.setSchema(mDatabaseName, schemaBundles, request.isForceOverride(),
+ new IAppSearchResultCallback.Stub() {
+ public void onResult(AppSearchResult result) {
+ executor.execute(() -> callback.accept(result));
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Indexes documents into AppSearch.
+ *
+ * <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
+ * schema type previously registered via the {@link #setSchema} method.
+ *
+ * @param request {@link PutDocumentsRequest} containing documents to be indexed
+ * @param executor Executor on which to invoke the callback.
+ * @param callback Callback to receive pending result of performing this operation. The keys
+ * of the returned {@link AppSearchBatchResult} are the URIs of the input
+ * documents. The values are {@code null} if they were successfully indexed,
+ * or a failed {@link AppSearchResult} otherwise.
+ * Or {@link BatchResultCallback#onSystemError} will be invoked with an
+ * {@link AppSearchException} if an error occurred in AppSearch initialization
+ * or a cause {@link Throwable} if other error occurred in AppSearch service.
+ */
+ public void putDocuments(
+ @NonNull PutDocumentsRequest request,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull BatchResultCallback<String, Void> callback) {
+ Objects.requireNonNull(request);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ List<GenericDocument> documents = request.getDocuments();
+ List<Bundle> documentBundles = new ArrayList<>(documents.size());
+ for (int i = 0; i < documents.size(); i++) {
+ documentBundles.add(documents.get(i).getBundle());
+ }
+ try {
+ mService.putDocuments(mDatabaseName, documentBundles,
+ new IAppSearchBatchResultCallback.Stub() {
+ public void onResult(AppSearchBatchResult result) {
+ executor.execute(() -> callback.onResult(result));
+ }
+
+ public void onSystemError(ParcelableException exception) {
+ executor.execute(() -> callback.onSystemError(exception.getCause()));
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Retrieves {@link GenericDocument}s by URI.
+ *
+ * @param request {@link GetByUriRequest} containing URIs to be retrieved.
+ * @param executor Executor on which to invoke the callback.
+ * @param callback Callback to receive the pending result of performing this operation. The keys
+ * of the returned {@link AppSearchBatchResult} are the input URIs. The values
+ * are the returned {@link GenericDocument}s on success, or a failed
+ * {@link AppSearchResult} otherwise. URIs that are not found will return a
+ * failed {@link AppSearchResult} with a result code of
+ * {@link AppSearchResult#RESULT_NOT_FOUND}.
+ * Or {@link BatchResultCallback#onSystemError} will be invoked with an
+ * {@link AppSearchException} if an error occurred in AppSearch initialization
+ * or a cause {@link Throwable} if other error occurred in AppSearch service.
+ */
+ public void getByUri(
+ @NonNull GetByUriRequest request,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull BatchResultCallback<String, GenericDocument> callback) {
+ Objects.requireNonNull(request);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ try {
+ mService.getDocuments(mDatabaseName, request.getNamespace(),
+ new ArrayList<>(request.getUris()),
+ new IAppSearchBatchResultCallback.Stub() {
+ public void onResult(AppSearchBatchResult result) {
+ executor.execute(() -> {
+ AppSearchBatchResult.Builder<String, GenericDocument>
+ documentResultBuilder =
+ new AppSearchBatchResult.Builder<>();
+
+ // Translate successful results
+ for (Map.Entry<String, Bundle> bundleEntry :
+ (Set<Map.Entry<String, Bundle>>)
+ result.getSuccesses().entrySet()) {
+ GenericDocument document;
+ try {
+ document = new GenericDocument(bundleEntry.getValue());
+ } catch (Throwable t) {
+ // These documents went through validation, so how could
+ // this fail? We must have done something wrong.
+ documentResultBuilder.setFailure(
+ bundleEntry.getKey(),
+ AppSearchResult.RESULT_INTERNAL_ERROR,
+ t.getMessage());
+ continue;
+ }
+ documentResultBuilder.setSuccess(
+ bundleEntry.getKey(), document);
+ }
+
+ // Translate failed results
+ for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry :
+ (Set<Map.Entry<String, AppSearchResult<Bundle>>>)
+ result.getFailures().entrySet()) {
+ documentResultBuilder.setFailure(
+ bundleEntry.getKey(),
+ bundleEntry.getValue().getResultCode(),
+ bundleEntry.getValue().getErrorMessage());
+ }
+ callback.onResult(documentResultBuilder.build());
+ });
+ }
+
+ public void onSystemError(ParcelableException exception) {
+ executor.execute(() -> callback.onSystemError(exception.getCause()));
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Removes {@link GenericDocument}s from the index by URI.
+ *
+ * @param request Request containing URIs to be removed.
+ * @param executor Executor on which to invoke the callback.
+ * @param callback Callback to receive the pending result of performing this operation. The keys
+ * of the returned {@link AppSearchBatchResult} are the input URIs. The values
+ * are {@code null} on success, or a failed {@link AppSearchResult} otherwise.
+ * URIs that are not found will return a failed {@link AppSearchResult} with a
+ * result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
+ * Or {@link BatchResultCallback#onSystemError} will be invoked with an
+ * {@link AppSearchException} if an error occurred in AppSearch initialization
+ * or a cause {@link Throwable} if other error occurred in AppSearch service.
+ */
+ public void removeByUri(
+ @NonNull RemoveByUriRequest request,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull BatchResultCallback<String, Void> callback) {
+ Objects.requireNonNull(request);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ try {
+ mService.removeByUri(mDatabaseName, request.getNamespace(),
+ new ArrayList<>(request.getUris()),
+ new IAppSearchBatchResultCallback.Stub() {
+ public void onResult(AppSearchBatchResult result) {
+ executor.execute(() -> callback.onResult(result));
+ }
+
+ public void onSystemError(ParcelableException exception) {
+ executor.execute(() -> callback.onSystemError(exception.getCause()));
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ // TODO(b/162450968) port query() and SearchResults.java to platform.
+ // TODO(b/162450968) port removeByQuery() to platform.
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java b/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java
new file mode 100644
index 000000000000..1689e02c7ce4
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+/**
+ * The callback interface to return {@link AppSearchBatchResult}.
+ *
+ * @param <KeyType> The type of the keys for {@link AppSearchBatchResult#getSuccesses} and
+ * {@link AppSearchBatchResult#getFailures}.
+ * @param <ValueType> The type of result objects associated with the keys.
+ * @hide
+ */
+public interface BatchResultCallback<KeyType, ValueType> {
+
+ /**
+ * Called when {@link AppSearchBatchResult} results are ready.
+ *
+ * @param result The result of the executed request.
+ */
+ void onResult(AppSearchBatchResult<KeyType, ValueType> result);
+
+
+ /**
+ * Called when a system error occurred.
+ *
+ * @param throwable The cause throwable.
+ */
+ default void onSystemError(Throwable throwable) {
+ if (throwable != null) {
+ throw new RuntimeException(throwable);
+ }
+ }
+}
diff --git a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchBatchResultCallback.aidl
index 138782bf5d19..b1bbd18b98e2 100644
--- a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchBatchResultCallback.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
+/**
+ * Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -13,18 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.app.appsearch;
-syntax = "proto2";
-package android.stats.mediaprovider;
-option java_multiple_files = true;
+import android.app.appsearch.AppSearchBatchResult;
+import android.os.ParcelableException;
-enum VolumeType {
- // Volume is unknown
- UNKNOWN = 0;
- // Volume is MediaStore.VOLUME_INTERNAL
- INTERNAL = 1;
- // Volume is MediaStore.VOLUME_EXTERNAL_PRIMARY
- EXTERNAL_PRIMARY = 2;
- // Volume is non-primary external storage
- EXTERNAL_OTHER = 3;
-}
+/** {@hide} */
+oneway interface IAppSearchBatchResultCallback {
+ void onResult(in AppSearchBatchResult result);
+ void onSystemError(in ParcelableException exception);
+} \ No newline at end of file
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 01260ea193f6..4a981022da73 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -17,10 +17,12 @@ package android.app.appsearch;
import android.os.Bundle;
+import android.app.appsearch.AppSearchBatchResult;
+import android.app.appsearch.AppSearchResult;
+import android.app.appsearch.IAppSearchBatchResultCallback;
+import android.app.appsearch.IAppSearchResultCallback;
import com.android.internal.infra.AndroidFuture;
-parcelable AppSearchResult;
-parcelable AppSearchBatchResult;
parcelable SearchResults;
/** {@hide} */
@@ -32,14 +34,14 @@ interface IAppSearchManager {
* @param schemaBundles List of AppSearchSchema bundles.
* @param forceOverride Whether to apply the new schema even if it is incompatible. All
* incompatible documents will be deleted.
- * @param callback {@link AndroidFuture}&lt;{@link AppSearchResult}&lt;{@link Void}&gt&gt;.
- * The results of the call.
+ * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+ * {@link AppSearchResult}&lt;{@link Void}&gt;.
*/
void setSchema(
in String databaseName,
in List<Bundle> schemaBundles,
boolean forceOverride,
- in AndroidFuture<AppSearchResult> callback);
+ in IAppSearchResultCallback callback);
/**
* Inserts documents into the index.
@@ -47,16 +49,16 @@ interface IAppSearchManager {
* @param databaseName The name of the database where this document lives.
* @param documentBundes List of GenericDocument bundles.
* @param callback
- * {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;&gt;.
- * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
- * {@code callback} will be completed with an
+ * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
+ * will be called with the cause throwable. Otherwise,
+ * {@link IAppSearchBatchResultCallback#onResult} will be called with an
* {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
* where the keys are document URIs, and the values are {@code null}.
*/
void putDocuments(
in String databaseName,
in List<Bundle> documentBundles,
- in AndroidFuture<AppSearchBatchResult> callback);
+ in IAppSearchBatchResultCallback callback);
/**
* Retrieves documents from the index.
@@ -65,9 +67,9 @@ interface IAppSearchManager {
* @param namespace The namespace this document resides in.
* @param uris The URIs of the documents to retrieve
* @param callback
- * {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Bundle}&gt;&gt;.
- * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
- * {@code callback} will be completed with an
+ * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
+ * will be called with the cause throwable. Otherwise,
+ * {@link IAppSearchBatchResultCallback#onResult} will be called with an
* {@link AppSearchBatchResult}&lt;{@link String}, {@link Bundle}&gt;
* where the keys are document URIs, and the values are Document bundles.
*/
@@ -75,7 +77,7 @@ interface IAppSearchManager {
in String databaseName,
in String namespace,
in List<String> uris,
- in AndroidFuture<AppSearchBatchResult> callback);
+ in IAppSearchBatchResultCallback callback);
/**
* Searches a document based on a given specifications.
@@ -98,9 +100,9 @@ interface IAppSearchManager {
* @param namespace Namespace of the document to remove.
* @param uris The URIs of the documents to delete
* @param callback
- * {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;&gt;.
- * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
- * {@code callback} will be completed with an
+ * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
+ * will be called with the cause throwable. Otherwise,
+ * {@link IAppSearchBatchResultCallback#onResult} will be called with an
* {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
* where the keys are document URIs. If a document doesn't exist, it will be reported as a
* failure where the {@code throwable} is {@code null}.
@@ -109,7 +111,7 @@ interface IAppSearchManager {
in String databaseName,
in String namespace,
in List<String> uris,
- in AndroidFuture<AppSearchBatchResult> callback);
+ in IAppSearchBatchResultCallback callback);
/**
* Removes documents by given query.
@@ -124,4 +126,12 @@ interface IAppSearchManager {
in String queryExpression,
in Bundle searchSpecBundle,
in AndroidFuture<AppSearchResult> callback);
+
+ /**
+ * Creates and initializes AppSearchImpl for the calling app.
+ *
+ * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
+ * {@link AppSearchResult}&lt;{@link Void}&gt;.
+ */
+ void initialize(in IAppSearchResultCallback callback);
}
diff --git a/core/proto/android/bluetooth/hfp/enums.proto b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchResultCallback.aidl
index d286e4b64d67..27729a5ad058 100644
--- a/core/proto/android/bluetooth/hfp/enums.proto
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchResultCallback.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright 2018 The Android Open Source Project
+/**
+ * Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -13,16 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.app.appsearch;
-syntax = "proto2";
-package android.bluetooth.hfp;
+import android.app.appsearch.AppSearchResult;
+import android.os.ParcelableException;
-option java_outer_classname = "BluetoothHfpProtoEnums";
-option java_multiple_files = true;
-
-enum ScoCodec {
- SCO_CODEC_UNKNOWN = 0;
- SCO_CODEC_CVSD = 1;
- // Default codec behind Wide Band Speech
- SCO_CODEC_MSBC = 2;
+/** {@hide} */
+oneway interface IAppSearchResultCallback {
+ void onResult(in AppSearchResult result);
} \ No newline at end of file
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 1dfde528e69b..8269799d5a0d 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -15,27 +15,32 @@
*/
package com.android.server.appsearch;
+import static android.app.appsearch.AppSearchResult.throwableToFailedResult;
+
import android.annotation.NonNull;
import android.app.appsearch.AppSearchBatchResult;
import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
+import android.app.appsearch.IAppSearchBatchResultCallback;
import android.app.appsearch.IAppSearchManager;
+import android.app.appsearch.IAppSearchResultCallback;
import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
-import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context;
import android.os.Binder;
import android.os.Bundle;
+import android.os.ParcelableException;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
+import android.util.Log;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
-import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -61,10 +66,9 @@ public class AppSearchManagerService extends SystemService {
@NonNull String databaseName,
@NonNull List<Bundle> schemaBundles,
boolean forceOverride,
- @NonNull AndroidFuture<AppSearchResult> callback) {
+ @NonNull IAppSearchResultCallback callback) {
Preconditions.checkNotNull(databaseName);
Preconditions.checkNotNull(schemaBundles);
- Preconditions.checkNotNull(callback);
int callingUid = Binder.getCallingUidOrThrow();
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
@@ -76,9 +80,10 @@ public class AppSearchManagerService extends SystemService {
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
impl.setSchema(databaseName, schemas, forceOverride);
- callback.complete(AppSearchResult.newSuccessfulResult(/*result=*/ null));
+ invokeCallbackOnResult(callback,
+ AppSearchResult.newSuccessfulResult(/*result=*/ null));
} catch (Throwable t) {
- callback.complete(throwableToFailedResult(t));
+ invokeCallbackOnError(callback, t);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
@@ -88,7 +93,7 @@ public class AppSearchManagerService extends SystemService {
public void putDocuments(
@NonNull String databaseName,
@NonNull List<Bundle> documentBundles,
- @NonNull AndroidFuture<AppSearchBatchResult> callback) {
+ @NonNull IAppSearchBatchResultCallback callback) {
Preconditions.checkNotNull(databaseName);
Preconditions.checkNotNull(documentBundles);
Preconditions.checkNotNull(callback);
@@ -96,22 +101,24 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
- databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>();
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
+ databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
for (int i = 0; i < documentBundles.size(); i++) {
GenericDocument document = new GenericDocument(documentBundles.get(i));
try {
+ // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
+ // a separate thread.
impl.putDocument(databaseName, document);
resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
} catch (Throwable t) {
resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
}
}
- callback.complete(resultBuilder.build());
+ invokeCallbackOnResult(callback, resultBuilder.build());
} catch (Throwable t) {
- callback.completeExceptionally(t);
+ invokeCallbackOnError(callback, t);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
@@ -119,7 +126,8 @@ public class AppSearchManagerService extends SystemService {
@Override
public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
- @NonNull List<String> uris, @NonNull AndroidFuture<AppSearchBatchResult> callback) {
+ @NonNull List<String> uris,
+ @NonNull IAppSearchBatchResultCallback callback) {
Preconditions.checkNotNull(databaseName);
Preconditions.checkNotNull(namespace);
Preconditions.checkNotNull(uris);
@@ -128,10 +136,10 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
- databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
new AppSearchBatchResult.Builder<>();
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
+ databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
for (int i = 0; i < uris.size(); i++) {
String uri = uris.get(i);
try {
@@ -141,9 +149,9 @@ public class AppSearchManagerService extends SystemService {
resultBuilder.setResult(uri, throwableToFailedResult(t));
}
}
- callback.complete(resultBuilder.build());
+ invokeCallbackOnResult(callback, resultBuilder.build());
} catch (Throwable t) {
- callback.completeExceptionally(t);
+ invokeCallbackOnError(callback, t);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
@@ -182,19 +190,19 @@ public class AppSearchManagerService extends SystemService {
@Override
public void removeByUri(@NonNull String databaseName, @NonNull String namespace,
- List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
+ @NonNull List<String> uris,
+ @NonNull IAppSearchBatchResultCallback callback) {
Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(namespace);
Preconditions.checkNotNull(uris);
Preconditions.checkNotNull(callback);
int callingUid = Binder.getCallingUidOrThrow();
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
+ AppSearchBatchResult.Builder<String, Void> resultBuilder =
+ new AppSearchBatchResult.Builder<>();
try {
AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
- AppSearchBatchResult.Builder<String, Void> resultBuilder =
- new AppSearchBatchResult.Builder<>();
for (int i = 0; i < uris.size(); i++) {
String uri = uris.get(i);
try {
@@ -204,9 +212,9 @@ public class AppSearchManagerService extends SystemService {
resultBuilder.setResult(uri, throwableToFailedResult(t));
}
}
- callback.complete(resultBuilder.build());
+ invokeCallbackOnResult(callback, resultBuilder.build());
} catch (Throwable t) {
- callback.completeExceptionally(t);
+ invokeCallbackOnError(callback, t);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
@@ -237,6 +245,21 @@ public class AppSearchManagerService extends SystemService {
}
}
+ @Override
+ public void initialize(@NonNull IAppSearchResultCallback callback) {
+ int callingUid = Binder.getCallingUidOrThrow();
+ int callingUserId = UserHandle.getUserId(callingUid);
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ ImplInstanceManager.getInstance(getContext(), callingUserId);
+ invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
+ } catch (Throwable t) {
+ invokeCallbackOnError(callback, t);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
/**
* Rewrites the database name by adding a prefix of unique name for the given uid.
*
@@ -256,23 +279,51 @@ public class AppSearchManagerService extends SystemService {
return callingUidName + CALLING_NAME_DATABASE_DELIMITER + databaseName;
}
- private <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
- @NonNull Throwable t) {
- if (t instanceof AppSearchException) {
- return ((AppSearchException) t).toAppSearchResult();
+ /** Invokes the {@link IAppSearchResultCallback} with the result. */
+ private void invokeCallbackOnResult(IAppSearchResultCallback callback,
+ AppSearchResult result) {
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ Log.d(TAG, "Unable to send result to the callback", e);
}
+ }
- @AppSearchResult.ResultCode int resultCode;
- if (t instanceof IllegalStateException) {
- resultCode = AppSearchResult.RESULT_INTERNAL_ERROR;
- } else if (t instanceof IllegalArgumentException) {
- resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
- } else if (t instanceof IOException) {
- resultCode = AppSearchResult.RESULT_IO_ERROR;
- } else {
- resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
+ /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
+ private void invokeCallbackOnResult(IAppSearchBatchResultCallback callback,
+ AppSearchBatchResult result) {
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ Log.d(TAG, "Unable to send result to the callback", e);
+ }
+ }
+
+ /**
+ * Invokes the {@link IAppSearchResultCallback} with an throwable.
+ *
+ * <p>The throwable is convert to a {@link AppSearchResult};
+ */
+ private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
+ try {
+ callback.onResult(throwableToFailedResult(throwable));
+ } catch (RemoteException e) {
+ Log.d(TAG, "Unable to send result to the callback", e);
+ }
+ }
+
+ /**
+ * Invokes the {@link IAppSearchBatchResultCallback} with an throwable.
+ *
+ * <p>The throwable is converted to {@link ParcelableException}.
+ */
+ private void invokeCallbackOnError(IAppSearchBatchResultCallback callback,
+ Throwable throwable) {
+ try {
+ callback.onSystemError(new ParcelableException(throwable));
+ } catch (RemoteException e) {
+ Log.d(TAG, "Unable to send error to the callback", e);
}
- return AppSearchResult.newFailedResult(resultCode, t.getMessage());
}
}
}
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 046145f90808..3b4823e799ce 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -605,6 +605,7 @@ bool BootAnimation::threadLoop() {
result = movie();
}
+ mCallbacks->shutdown();
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
@@ -691,7 +692,6 @@ void BootAnimation::checkExit() {
int exitnow = atoi(value);
if (exitnow) {
requestExit();
- mCallbacks->shutdown();
}
}
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 41bdff8a464c..bde59f497b19 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -16,8 +16,8 @@
#include <gtest/gtest.h>
-#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h"
#include "frameworks/proto_logging/stats/atoms.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/launcher/launcher.pb.h"
#include "log/log_event_list.h"
#include "stats_event.h"
diff --git a/core/api/current.txt b/core/api/current.txt
index 01c2b625ead6..e302b25873b4 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40978,6 +40978,19 @@ package android.se.omapi {
package android.security {
+ public final class AppUriAuthenticationPolicy implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.Map<java.lang.String,java.util.Map<android.net.Uri,java.lang.String>> getAppAndUriMappings();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.security.AppUriAuthenticationPolicy> CREATOR;
+ }
+
+ public static final class AppUriAuthenticationPolicy.Builder {
+ ctor public AppUriAuthenticationPolicy.Builder();
+ method @NonNull public android.security.AppUriAuthenticationPolicy.Builder addAppAndUriMapping(@NonNull String, @NonNull android.net.Uri, @NonNull String);
+ method @NonNull public android.security.AppUriAuthenticationPolicy build();
+ }
+
public final class AttestedKeyPair {
ctor public AttestedKeyPair(@Nullable java.security.KeyPair, @NonNull java.util.List<java.security.cert.Certificate>);
method @NonNull public java.util.List<java.security.cert.Certificate> getAttestationRecord();
@@ -41025,6 +41038,7 @@ package android.security {
method public static void choosePrivateKeyAlias(@NonNull android.app.Activity, @NonNull android.security.KeyChainAliasCallback, @Nullable String[], @Nullable java.security.Principal[], @Nullable String, int, @Nullable String);
method public static void choosePrivateKeyAlias(@NonNull android.app.Activity, @NonNull android.security.KeyChainAliasCallback, @Nullable String[], @Nullable java.security.Principal[], @Nullable android.net.Uri, @Nullable String);
method @NonNull public static android.content.Intent createInstallIntent();
+ method @NonNull public static android.content.Intent createManageCredentialsIntent(@NonNull android.security.AppUriAuthenticationPolicy);
method @Nullable @WorkerThread public static java.security.cert.X509Certificate[] getCertificateChain(@NonNull android.content.Context, @NonNull String) throws java.lang.InterruptedException, android.security.KeyChainException;
method @Nullable @WorkerThread public static java.security.PrivateKey getPrivateKey(@NonNull android.content.Context, @NonNull String) throws java.lang.InterruptedException, android.security.KeyChainException;
method @Deprecated public static boolean isBoundKeyAlgorithm(@NonNull String);
@@ -44555,6 +44569,7 @@ package android.telecom {
method public android.telecom.PhoneAccount.Builder toBuilder();
method public void writeToParcel(android.os.Parcel, int);
field public static final int CAPABILITY_ADHOC_CONFERENCE_CALLING = 16384; // 0x4000
+ field public static final int CAPABILITY_CALL_COMPOSER = 32768; // 0x8000
field public static final int CAPABILITY_CALL_PROVIDER = 2; // 0x2
field public static final int CAPABILITY_CALL_SUBJECT = 64; // 0x40
field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7d82f43af975..99179ec89cbc 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6693,6 +6693,7 @@ package android.net {
method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
method public final void sendSocketKeepaliveEvent(int, int);
+ method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
method public void unregister();
field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 52a79bae6324..5434bcca0575 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -832,6 +832,14 @@ package android.hardware.soundtrigger {
}
+package android.inputmethodservice {
+
+ public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
+ field public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // 0x94fa793L
+ }
+
+}
+
package android.location {
public final class GnssClock implements android.os.Parcelable {
@@ -2082,12 +2090,15 @@ package android.view {
}
public interface WindowManager extends android.view.ViewManager {
+ method public default int getDisplayImePolicy(int);
method public default void holdLock(android.os.IBinder, int);
- method public default void setShouldShowIme(int, boolean);
+ method public default void setDisplayImePolicy(int, int);
method public default void setShouldShowSystemDecors(int, boolean);
method public default void setShouldShowWithInsecureKeyguard(int, boolean);
- method public default boolean shouldShowIme(int);
method public default boolean shouldShowSystemDecors(int);
+ field public static final int DISPLAY_IME_POLICY_FALLBACK_DISPLAY = 1; // 0x1
+ field public static final int DISPLAY_IME_POLICY_HIDE = 2; // 0x2
+ field public static final int DISPLAY_IME_POLICY_LOCAL = 0; // 0x0
}
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index 862563706da7..a60e6428418d 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -114,15 +114,6 @@ public final class SharedLibraryInfo implements Parcelable {
mIsNative = isNative;
}
- /** @hide */
- public SharedLibraryInfo(String path, String packageName, List<String> codePaths,
- String name, long version, int type,
- VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages,
- List<SharedLibraryInfo> dependencies) {
- this(path, packageName, codePaths, name, version, type, declaringPackage, dependentPackages,
- dependencies, false /* isNative */);
- }
-
private SharedLibraryInfo(Parcel parcel) {
mPath = parcel.readString8();
mPackageName = parcel.readString8();
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 7fb73ceab4f4..81ea2f5a17dd 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -56,6 +56,7 @@ import android.view.PointerIcon;
import android.view.VerifiedInputEvent;
import android.view.WindowManager.LayoutParams;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
@@ -275,6 +276,21 @@ public final class InputManager {
*
* @hide
*/
+ @VisibleForTesting
+ public static InputManager resetInstance(IInputManager inputManagerService) {
+ synchronized (InputManager.class) {
+ sInstance = new InputManager(inputManagerService);
+ return sInstance;
+ }
+ }
+
+ /**
+ * Gets an instance of the input manager.
+ *
+ * @return The input manager instance.
+ *
+ * @hide
+ */
@UnsupportedAppUsage
public static InputManager getInstance() {
synchronized (InputManager.class) {
@@ -1428,7 +1444,7 @@ public final class InputManager {
@Override
public boolean hasAmplitudeControl() {
- return false;
+ return true;
}
/**
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index e9de27456f97..0766917642e8 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -54,6 +54,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
private static final int DO_VIEW_CLICKED = 115;
private static final int DO_NOTIFY_IME_HIDDEN = 120;
private static final int DO_REMOVE_IME_SURFACE = 130;
+ private static final int DO_FINISH_INPUT = 140;
+
@UnsupportedAppUsage
HandlerCaller mCaller;
@@ -141,6 +143,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
mInputMethodSession.removeImeSurface();
return;
}
+ case DO_FINISH_INPUT: {
+ mInputMethodSession.finishInput();
+ return;
+ }
}
Log.w(TAG, "Unhandled message code: " + msg.what);
}
@@ -222,6 +228,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_SESSION));
}
+ @Override
+ public void finishInput() {
+ mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_INPUT));
+ }
private final class ImeInputEventReceiver extends InputEventReceiver
implements InputMethodSession.EventCallback {
private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>();
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index ae260e16806f..4a5d831cd705 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -61,9 +61,12 @@ import android.annotation.IntDef;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.annotation.UiContext;
import android.app.ActivityManager;
import android.app.Dialog;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -411,7 +414,29 @@ public class InputMethodService extends AbstractInputMethodService {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
int mTheme = 0;
-
+
+ /**
+ * Finish the {@link InputConnection} when the device becomes
+ * {@link android.os.PowerManager#isInteractive non-interactive}.
+ *
+ * <p>
+ * If enabled by the current {@link InputMethodService input method}, the current input
+ * connection will be {@link InputMethodService#onFinishInput finished} whenever the devices
+ * becomes non-interactive.
+ *
+ * <p>
+ * If not enabled, the current input connection will instead be silently deactivated when the
+ * devices becomes non-interactive, and an {@link InputMethodService#onFinishInput
+ * onFinishInput()} {@link InputMethodService#onStartInput onStartInput()} pair is dispatched
+ * when the device becomes interactive again.
+ *
+ * @hide
+ */
+ @TestApi
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // This is a bug id.
+
LayoutInflater mInflater;
TypedArray mThemeAttrs;
@UnsupportedAppUsage
@@ -2325,7 +2350,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) {
- if (!restarting) {
+ if (!restarting && mInputStarted) {
doFinishInput();
}
ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this);
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
index dbb669be1402..2db9ed1103fa 100644
--- a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
@@ -23,6 +23,7 @@ import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Looper;
+import android.os.RemoteException;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.InputChannel;
@@ -38,8 +39,8 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.inputmethod.IMultiClientInputMethodSession;
import com.android.internal.inputmethod.CancellationGroup;
+import com.android.internal.inputmethod.IMultiClientInputMethodSession;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.view.IInputContext;
@@ -303,6 +304,12 @@ final class MultiClientInputMethodClientCallbackAdaptor {
// no-op for multi-session
reportNotSupported();
}
+
+ @Override
+ public void finishInput() throws RemoteException {
+ // no-op for multi-session
+ reportNotSupported();
+ }
}
private static final class MultiClientInputMethodSessionImpl
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 44ebff99f3e9..0676ad4e2322 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -40,6 +40,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.Duration;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -174,6 +175,14 @@ public abstract class NetworkAgent {
public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
/**
+ * Sent by the NetworkAgent to ConnectivityService to pass the current
+ * list of underlying networks.
+ * obj = array of Network objects
+ * @hide
+ */
+ public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5;
+
+ /**
* Sent by ConnectivityService to the NetworkAgent to inform the agent of the
* networks status - whether we could use the network or could not, due to
* either a bad network configuration (no internet link) or captive portal.
@@ -217,7 +226,13 @@ public abstract class NetworkAgent {
* The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}.
* @hide
*/
- public static String REDIRECT_URL_KEY = "redirect URL";
+ public static final String REDIRECT_URL_KEY = "redirect URL";
+
+ /**
+ * Bundle key for the underlying networks in {@code EVENT_UNDERLYING_NETWORKS_CHANGED}.
+ * @hide
+ */
+ public static final String UNDERLYING_NETWORKS_KEY = "underlyingNetworks";
/**
* Sent by the NetworkAgent to ConnectivityService to indicate this network was
@@ -650,6 +665,33 @@ public abstract class NetworkAgent {
}
/**
+ * Must be called by the agent when the network's underlying networks change.
+ *
+ * <p>{@code networks} is one of the following:
+ * <ul>
+ * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in
+ * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular)
+ * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear
+ * first in the array.</li>
+ * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no
+ * underlying network connection, and thus, app traffic will not be sent or received.</li>
+ * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's
+ * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket}
+ * APIs mentioned above to send traffic over specific channels.</li>
+ * </ul>
+ *
+ * @param underlyingNetworks the new list of underlying networks.
+ * @see {@link VpnService.Builder#setUnderlyingNetworks(Network[])}
+ */
+ public final void setUnderlyingNetworks(@Nullable List<Network> underlyingNetworks) {
+ final ArrayList<Network> underlyingArray = (underlyingNetworks != null)
+ ? new ArrayList<>(underlyingNetworks) : null;
+ final Bundle bundle = new Bundle();
+ bundle.putParcelableArrayList(UNDERLYING_NETWORKS_KEY, underlyingArray);
+ queueOrSendMessage(EVENT_UNDERLYING_NETWORKS_CHANGED, bundle);
+ }
+
+ /**
* Inform ConnectivityService that this agent has now connected.
* Call {@link #unregister} to disconnect.
*/
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 40bb8bf11d0b..8dad11ffa731 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -712,6 +712,7 @@ public final class NetworkCapabilities implements Parcelable {
if (ArrayUtils.contains(originalAdministratorUids, creatorUid)) {
setAdministratorUids(new int[] {creatorUid});
}
+ // There is no need to clear the UIDs, they have already been cleared by clearAll() above.
}
/**
@@ -805,7 +806,9 @@ public final class NetworkCapabilities implements Parcelable {
*/
private static final int TEST_NETWORKS_ALLOWED_TRANSPORTS = 1 << TRANSPORT_TEST
// Test ethernet networks can be created with EthernetManager#setIncludeTestInterfaces
- | 1 << TRANSPORT_ETHERNET;
+ | 1 << TRANSPORT_ETHERNET
+ // Test VPN networks can be created but their UID ranges must be empty.
+ | 1 << TRANSPORT_VPN;
/**
* Adds the given transport type to this {@code NetworkCapability} instance.
diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java
index d31218d9b67b..a17a49897d39 100644
--- a/core/java/android/net/NetworkProvider.java
+++ b/core/java/android/net/NetworkProvider.java
@@ -51,13 +51,6 @@ public class NetworkProvider {
public static final int ID_NONE = -1;
/**
- * A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any
- * provider, so they use this constant for clarity instead of NONE.
- * @hide only used by ConnectivityService.
- */
- public static final int ID_VPN = -2;
-
- /**
* The first providerId value that will be allocated.
* @hide only used by ConnectivityService.
*/
diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java
index 95c07b6b2451..fb9fa109bfa3 100644
--- a/core/java/android/os/ParcelableHolder.java
+++ b/core/java/android/os/ParcelableHolder.java
@@ -170,16 +170,21 @@ public final class ParcelableHolder implements Parcelable {
mParcelable = null;
+ int dataSize = parcel.readInt();
+ if (dataSize < 0) {
+ throw new IllegalArgumentException("dataSize from parcel is negative");
+ } else if (dataSize == 0) {
+ if (mParcel != null) {
+ mParcel.recycle();
+ mParcel = null;
+ }
+ return;
+ }
if (mParcel == null) {
mParcel = Parcel.obtain();
}
mParcel.setDataPosition(0);
mParcel.setDataSize(0);
-
- int dataSize = parcel.readInt();
- if (dataSize < 0) {
- throw new IllegalArgumentException("dataSize from parcel is negative");
- }
int dataStartPos = parcel.dataPosition();
mParcel.appendFrom(parcel, dataStartPos, dataSize);
@@ -196,6 +201,11 @@ public final class ParcelableHolder implements Parcelable {
return;
}
+ if (mParcelable == null) {
+ parcel.writeInt(0);
+ return;
+ }
+
int sizePos = parcel.dataPosition();
parcel.writeInt(0);
int dataStartPos = parcel.dataPosition();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 053353330e4e..1a6eea554cae 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -648,24 +648,24 @@ interface IWindowManager
void setShouldShowSystemDecors(int displayId, boolean shouldShow);
/**
- * Indicates that the display should show IME.
+ * Indicates the policy for how the display should show IME.
*
* @param displayId The id of the display.
- * @return {@code true} if the display should show IME.
+ * @return The policy for how the display should show IME.
* @see KeyguardManager#isDeviceSecure()
* @see KeyguardManager#isDeviceLocked()
*/
- boolean shouldShowIme(int displayId);
+ int getDisplayImePolicy(int displayId);
/**
- * Sets that the display should show IME.
+ * Sets the policy for how the display should show IME.
*
* @param displayId The id of the display.
- * @param shouldShow Indicates that the display should show IME.
+ * @param imePolicy Indicates the policy for how the display should show IME.
* @see KeyguardManager#isDeviceSecure()
* @see KeyguardManager#isDeviceLocked()
*/
- void setShouldShowIme(int displayId, boolean shouldShow);
+ void setDisplayImePolicy(int displayId, int imePolicy);
/**
* Waits for transactions to get applied before injecting input, optionally waiting for
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index efc0bd2785f4..4a5c95f43d46 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -222,6 +222,25 @@ public final class ImeFocusController {
}
/**
+ * To handle the lifecycle of the input connection when the device interactivity state changed.
+ * (i.e. Calling IMS#onFinishInput when the device screen-off and Calling IMS#onStartInput
+ * when the device screen-on again).
+ */
+ @UiThread
+ public void onInteractiveChanged(boolean interactive) {
+ final InputMethodManagerDelegate immDelegate = getImmDelegate();
+ if (!immDelegate.isCurrentRootView(mViewRootImpl)) {
+ return;
+ }
+ if (interactive) {
+ final View focusedView = mViewRootImpl.mView.findFocus();
+ onViewFocusChanged(focusedView, focusedView != null);
+ } else {
+ mDelegate.finishInputAndReportToIme();
+ }
+ }
+
+ /**
* @param windowAttribute {@link WindowManager.LayoutParams} to be checked.
* @return Whether the window is in local focus mode or not.
*/
@@ -256,6 +275,7 @@ public final class ImeFocusController {
@WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags,
boolean forceNewFocus);
void finishInput();
+ void finishInputAndReportToIme();
void closeCurrentIme();
void finishComposingText();
void setCurrentRootView(ViewRootImpl rootView);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 22ac4dcd2cfe..8da833a28efa 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -29,6 +29,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.Vibrator;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -423,9 +425,13 @@ public final class InputDevice implements Parcelable {
}
};
- // Called by native code.
+ /**
+ * Called by native code
+ * @hide
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
+ @VisibleForTesting
+ public InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone,
boolean hasButtonUnderPad) {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 607888c81357..15adc5a0ec2f 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -239,7 +239,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private static boolean useBlastAdapter(Context context) {
ContentResolver contentResolver = context.getContentResolver();
return Settings.Global.getInt(contentResolver,
- Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV, 1 /* default */) == 1;
+ Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV, 0 /* default */) == 1;
}
private final boolean mUseBlastAdapter;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 436acef17c4d..ef2153e074e7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -461,6 +461,40 @@ public interface WindowManager extends ViewManager {
@interface RemoveContentMode {}
/**
+ * Display IME Policy: The IME should appear on the local display.
+ * @hide
+ */
+ @TestApi
+ int DISPLAY_IME_POLICY_LOCAL = 0;
+
+ /**
+ * Display IME Policy: The IME should appear on the fallback display.
+ * @hide
+ */
+ @TestApi
+ int DISPLAY_IME_POLICY_FALLBACK_DISPLAY = 1;
+
+ /**
+ * Display IME Policy: The IME should be hidden.
+ *
+ * Setting this policy will prevent the IME from making a connection. This
+ * will prevent any IME from receiving metadata about input.
+ * @hide
+ */
+ @TestApi
+ int DISPLAY_IME_POLICY_HIDE = 2;
+
+ /**
+ * @hide
+ */
+ @IntDef({
+ DISPLAY_IME_POLICY_LOCAL,
+ DISPLAY_IME_POLICY_FALLBACK_DISPLAY,
+ DISPLAY_IME_POLICY_HIDE,
+ })
+ @interface DisplayImePolicy {}
+
+ /**
* Exception that is thrown when trying to add view whose
* {@link LayoutParams} {@link LayoutParams#token}
* is invalid.
@@ -695,27 +729,26 @@ public interface WindowManager extends ViewManager {
}
/**
- * Sets that the display should show IME.
+ * Sets the policy for how the display should show IME.
*
* @param displayId Display ID.
- * @param shouldShow Indicates that the display should show IME.
+ * @param imePolicy Indicates the policy for how the display should show IME.
* @hide
*/
@TestApi
- default void setShouldShowIme(int displayId, boolean shouldShow) {
+ default void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) {
}
/**
- * Indicates that the display should show IME.
+ * Indicates the policy for how the display should show IME.
*
* @param displayId The id of the display.
- * @return {@code true} if the display should show IME when an input field becomes
- * focused on it.
+ * @return The policy for how the display should show IME.
* @hide
*/
@TestApi
- default boolean shouldShowIme(int displayId) {
- return false;
+ default @DisplayImePolicy int getDisplayImePolicy(int displayId) {
+ return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
}
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
@@ -2124,15 +2157,6 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
/**
- * Flag to indicate that this window should be considered a screen decoration similar to the
- * nav bar and status bar. This will cause this window to affect the window insets reported
- * to other windows when it is visible.
- * @hide
- */
- @RequiresPermission(permission.STATUS_BAR_SERVICE)
- public static final int PRIVATE_FLAG_IS_SCREEN_DECOR = 0x00400000;
-
- /**
* Flag to indicate that the status bar window is in a state such that it forces showing
* the navigation bar unless the navigation bar window is explicitly set to
* {@link View#GONE}.
@@ -2237,7 +2261,6 @@ public interface WindowManager extends ViewManager {
PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
- PRIVATE_FLAG_IS_SCREEN_DECOR,
PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
PRIVATE_FLAG_USE_BLAST,
@@ -2325,10 +2348,6 @@ public interface WindowManager extends ViewManager {
equals = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
name = "IS_ROUNDED_CORNERS_OVERLAY"),
@ViewDebug.FlagToString(
- mask = PRIVATE_FLAG_IS_SCREEN_DECOR,
- equals = PRIVATE_FLAG_IS_SCREEN_DECOR,
- name = "IS_SCREEN_DECOR"),
- @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
equals = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
name = "STATUS_FORCE_SHOW_NAVIGATION"),
@@ -2826,7 +2845,6 @@ public interface WindowManager extends ViewManager {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(
- flag = true,
value = {LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER,
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index d56929e06906..3384bbe4fd76 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -201,20 +201,20 @@ public final class WindowManagerImpl implements WindowManager {
}
@Override
- public void setShouldShowIme(int displayId, boolean shouldShow) {
+ public void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) {
try {
- WindowManagerGlobal.getWindowManagerService().setShouldShowIme(displayId, shouldShow);
+ WindowManagerGlobal.getWindowManagerService().setDisplayImePolicy(displayId, imePolicy);
} catch (RemoteException e) {
}
}
@Override
- public boolean shouldShowIme(int displayId) {
+ public @DisplayImePolicy int getDisplayImePolicy(int displayId) {
try {
- return WindowManagerGlobal.getWindowManagerService().shouldShowIme(displayId);
+ return WindowManagerGlobal.getWindowManagerService().getDisplayImePolicy(displayId);
} catch (RemoteException e) {
}
- return false;
+ return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
}
@Override
diff --git a/core/proto/android/stats/enums.proto b/core/java/android/view/inputmethod/DumpableInputConnection.java
index 8f8055ed2451..9819a5734491 100644
--- a/core/proto/android/stats/enums.proto
+++ b/core/java/android/view/inputmethod/DumpableInputConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +14,19 @@
* limitations under the License.
*/
-syntax = "proto2";
+package android.view.inputmethod;
-package android.stats;
-option java_outer_classname = "StatsEnums";
+import android.annotation.NonNull;
+import android.util.proto.ProtoOutputStream;
-enum EventType {
- // Unknown.
- TYPE_UNKNOWN = 0;
- CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_SUCCEEDED = 1;
- CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_FAILED = 2;
- CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_SUCCEEDED = 3;
- CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_FAILED = 4;
+/** @hide */
+public interface DumpableInputConnection {
+
+ /**
+ * Method used to dump state of InputConnection implementations of interest.
+ *
+ * @param proto Stream to write the state to
+ * @param fieldId FieldId of DumpableInputConnection as defined in the parent message
+ */
+ void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId);
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 3c89a4bfad59..c3d3985b5ac3 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -22,6 +22,7 @@ import static android.util.imetracing.ImeTracing.PROTO_ARG;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.DISPLAY_ID;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.EDITOR_INFO;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_INSETS_SOURCE_CONSUMER;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INPUT_CONNECTION;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INPUT_METHOD_MANAGER;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.VIEW_ROOT_IMPL;
import static android.view.inputmethod.InputMethodManagerProto.ACTIVE;
@@ -599,6 +600,27 @@ public final class InputMethodManager {
}
/**
+ * Used by {@link ImeFocusController} to finish input connection and callback
+ * {@link InputMethodService#onFinishInput()}.
+ *
+ * This method is especially for when ImeFocusController received device screen-off event to
+ * ensure the entire finish input connection and the connection lifecycle callback to
+ * IME can be done for security concern.
+ */
+ @Override
+ public void finishInputAndReportToIme() {
+ synchronized (mH) {
+ finishInputLocked();
+ if (mCurMethod != null) {
+ try {
+ mCurMethod.finishInput();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+
+ /**
* Used by {@link ImeFocusController} to hide current input method editor.
*/
@Override
@@ -849,12 +871,23 @@ public final class InputMethodManager {
case MSG_SET_ACTIVE: {
final boolean active = msg.arg1 != 0;
final boolean fullscreen = msg.arg2 != 0;
+ final boolean reportToImeController = msg.obj != null && (boolean) msg.obj;
if (DEBUG) {
Log.i(TAG, "handleMessage: MSG_SET_ACTIVE " + active + ", was " + mActive);
}
synchronized (mH) {
mActive = active;
mFullscreenMode = fullscreen;
+
+ // Report active state to ImeFocusController to handle IME input
+ // connection lifecycle callback when it allowed.
+ final ImeFocusController controller = getFocusController();
+ final View rootView = mCurRootView != null ? mCurRootView.getView() : null;
+ if (controller != null && rootView != null && reportToImeController) {
+ rootView.post(() -> controller.onInteractiveChanged(active));
+ return;
+ }
+
if (!active) {
// Some other client has starting using the IME, so note
// that this happened and make sure our own editor's
@@ -966,9 +999,9 @@ public final class InputMethodManager {
private final InputMethodManager mParentInputMethodManager;
private final WeakReference<View> mServedView;
- ControlledInputConnectionWrapper(Looper mainLooper, InputConnection conn,
+ ControlledInputConnectionWrapper(Looper icLooper, InputConnection conn,
InputMethodManager inputMethodManager, View servedView) {
- super(mainLooper, conn);
+ super(icLooper, conn);
mParentInputMethodManager = inputMethodManager;
mServedView = new WeakReference<>(servedView);
}
@@ -1014,6 +1047,18 @@ public final class InputMethodManager {
+ " mServedView=" + mServedView.get()
+ "}";
}
+
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ // Check that the call is initiated in the main thread of the current InputConnection
+ // {@link InputConnection#getHandler} since the messages to IInputConnectionWrapper are
+ // executed on this thread. Otherwise the messages are dispatched to the correct thread
+ // in IInputConnectionWrapper, but this is not wanted while dumpng, for performance
+ // reasons.
+ if (getInputConnection() instanceof DumpableInputConnection && Looper.myLooper()
+ == getLooper()) {
+ ((DumpableInputConnection) getInputConnection()).dumpDebug(proto, fieldId);
+ }
+ }
}
private static class ImeThreadFactory implements ThreadFactory {
@@ -1061,8 +1106,9 @@ public final class InputMethodManager {
}
@Override
- public void setActive(boolean active, boolean fullscreen) {
- mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0).sendToTarget();
+ public void setActive(boolean active, boolean fullscreen, boolean reportToImeController) {
+ mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0,
+ reportToImeController).sendToTarget();
}
@Override
@@ -2174,6 +2220,7 @@ public final class InputMethodManager {
* @hide
*/
public void notifyImeHidden(IBinder windowToken) {
+ ImeTracing.getInstance().triggerClientDump("InputMethodManager#notifyImeHidden", this);
synchronized (mH) {
try {
if (mCurMethod != null && mCurRootView != null
@@ -3279,6 +3326,9 @@ public final class InputMethodManager {
if (mImeInsetsConsumer != null) {
mImeInsetsConsumer.dumpDebug(proto, IME_INSETS_SOURCE_CONSUMER);
}
+ if (mServedInputConnectionWrapper != null) {
+ mServedInputConnectionWrapper.dumpDebug(proto, INPUT_CONNECTION);
+ }
}
}
}
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index a034a7c2dc7e..e08ccfddc4c5 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -156,8 +156,7 @@ public final class SelectionActionModeHelper {
mSmartSelectSprite != null
? this::startSelectionActionModeWithSmartSelectAnimation
: this::startSelectionActionMode,
- mTextClassificationHelper::getOriginalSelection,
- mTextClassificationHelper::isTextClassifierDestroyed)
+ mTextClassificationHelper::getOriginalSelection)
.execute();
}
}
@@ -179,8 +178,7 @@ public final class SelectionActionModeHelper {
mTextClassificationHelper.getTimeoutDuration(),
mTextClassificationHelper::classifyText,
this::startLinkActionMode,
- mTextClassificationHelper::getOriginalSelection,
- mTextClassificationHelper::isTextClassifierDestroyed)
+ mTextClassificationHelper::getOriginalSelection)
.execute();
}
}
@@ -196,8 +194,7 @@ public final class SelectionActionModeHelper {
mTextClassificationHelper.getTimeoutDuration(),
mTextClassificationHelper::classifyText,
this::invalidateActionMode,
- mTextClassificationHelper::getOriginalSelection,
- mTextClassificationHelper::isTextClassifierDestroyed)
+ mTextClassificationHelper::getOriginalSelection)
.execute();
}
}
@@ -995,7 +992,6 @@ public final class SelectionActionModeHelper {
private final Supplier<SelectionResult> mSelectionResultSupplier;
private final Consumer<SelectionResult> mSelectionResultCallback;
private final Supplier<SelectionResult> mTimeOutResultSupplier;
- private final Supplier<Boolean> mIsTextClassifierDestroyedSupplier;
private final TextView mTextView;
private final String mOriginalText;
@@ -1010,16 +1006,13 @@ public final class SelectionActionModeHelper {
@NonNull TextView textView, int timeOut,
@NonNull Supplier<SelectionResult> selectionResultSupplier,
@NonNull Consumer<SelectionResult> selectionResultCallback,
- @NonNull Supplier<SelectionResult> timeOutResultSupplier,
- @NonNull Supplier<Boolean> isTextClassifierDestroyedSupplier) {
+ @NonNull Supplier<SelectionResult> timeOutResultSupplier) {
super(textView != null ? textView.getHandler() : null);
mTextView = Objects.requireNonNull(textView);
mTimeOutDuration = timeOut;
mSelectionResultSupplier = Objects.requireNonNull(selectionResultSupplier);
mSelectionResultCallback = Objects.requireNonNull(selectionResultCallback);
mTimeOutResultSupplier = Objects.requireNonNull(timeOutResultSupplier);
- mIsTextClassifierDestroyedSupplier =
- Objects.requireNonNull(isTextClassifierDestroyedSupplier);
// Make a copy of the original text.
mOriginalText = getText(mTextView).toString();
}
@@ -1033,14 +1026,8 @@ public final class SelectionActionModeHelper {
try {
result = mSelectionResultSupplier.get();
} catch (IllegalStateException e) {
- // Swallows the exception if the text classifier session is destroyed
- if (mIsTextClassifierDestroyedSupplier.get()) {
- Log.w(LOG_TAG,
- "TextClassificationAsyncTask failed because TextClassifier destroyed",
- e);
- } else {
- throw e;
- }
+ // TODO(b/174300371): Only swallows the exception if the TCSession is destroyed
+ Log.w(LOG_TAG, "TextClassificationAsyncTask failed.", e);
}
mTextView.removeCallbacks(onTimeOut);
return result;
@@ -1173,10 +1160,6 @@ public final class SelectionActionModeHelper {
}
}
- public boolean isTextClassifierDestroyed() {
- return mTextClassifier.get().isDestroyed();
- }
-
private boolean isDarkLaunchEnabled() {
return TextClassificationManager.getSettings(mContext).isModelDarkLaunchEnabled();
}
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 0eef84765890..b4e7d6a9269f 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -19,6 +19,7 @@ package android.window;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -66,6 +67,9 @@ public final class TransitionInfo implements Parcelable {
private final @WindowManager.TransitionOldType int mType;
private final ArrayList<Change> mChanges = new ArrayList<>();
+ private SurfaceControl mRootLeash;
+ private final Point mRootOffset = new Point();
+
/** @hide */
public TransitionInfo(@WindowManager.TransitionOldType int type) {
mType = type;
@@ -74,6 +78,9 @@ public final class TransitionInfo implements Parcelable {
private TransitionInfo(Parcel in) {
mType = in.readInt();
in.readList(mChanges, null /* classLoader */);
+ mRootLeash = new SurfaceControl();
+ mRootLeash.readFromParcel(in);
+ mRootOffset.readFromParcel(in);
}
@Override
@@ -81,6 +88,8 @@ public final class TransitionInfo implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeList(mChanges);
+ mRootLeash.writeToParcel(dest, flags);
+ mRootOffset.writeToParcel(dest, flags);
}
@NonNull
@@ -103,10 +112,35 @@ public final class TransitionInfo implements Parcelable {
return 0;
}
+ /** @see #getRootLeash() */
+ public void setRootLeash(@NonNull SurfaceControl leash, int offsetLeft, int offsetTop) {
+ mRootLeash = leash;
+ mRootOffset.set(offsetLeft, offsetTop);
+ }
+
public int getType() {
return mType;
}
+ /**
+ * @return a surfacecontrol that can serve as a parent surfacecontrol for all the changing
+ * participants to animate within. This will generally be placed at the highest-z-order
+ * shared ancestor of all participants.
+ */
+ @NonNull
+ public SurfaceControl getRootLeash() {
+ if (mRootLeash == null) {
+ throw new IllegalStateException("Trying to get a leash which wasn't set");
+ }
+ return mRootLeash;
+ }
+
+ /** @return the offset (relative to the screen) of the root leash. */
+ @NonNull
+ public Point getRootOffset() {
+ return mRootOffset;
+ }
+
@NonNull
public List<Change> getChanges() {
return mChanges;
@@ -136,7 +170,7 @@ public final class TransitionInfo implements Parcelable {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("{t=" + mType + " c=[");
+ sb.append("{t=" + mType + " ro=" + mRootOffset + " c=[");
for (int i = 0; i < mChanges.size(); ++i) {
if (i > 0) {
sb.append(',');
@@ -167,8 +201,9 @@ public final class TransitionInfo implements Parcelable {
private WindowContainerToken mParent;
private final SurfaceControl mLeash;
private int mMode = TRANSIT_NONE;
- private final Rect mStartBounds = new Rect();
- private final Rect mEndBounds = new Rect();
+ private final Rect mStartAbsBounds = new Rect();
+ private final Rect mEndAbsBounds = new Rect();
+ private final Point mEndRelOffset = new Point();
public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) {
mContainer = container;
@@ -181,8 +216,9 @@ public final class TransitionInfo implements Parcelable {
mLeash = new SurfaceControl();
mLeash.readFromParcel(in);
mMode = in.readInt();
- mStartBounds.readFromParcel(in);
- mEndBounds.readFromParcel(in);
+ mStartAbsBounds.readFromParcel(in);
+ mEndAbsBounds.readFromParcel(in);
+ mEndRelOffset.readFromParcel(in);
}
/** Sets the parent of this change's container. The parent must be a participant or null. */
@@ -195,14 +231,19 @@ public final class TransitionInfo implements Parcelable {
mMode = mode;
}
- /** Sets the bounds this container occupied before the change */
- public void setStartBounds(@Nullable Rect rect) {
- mStartBounds.set(rect);
+ /** Sets the bounds this container occupied before the change in screen space */
+ public void setStartAbsBounds(@Nullable Rect rect) {
+ mStartAbsBounds.set(rect);
}
- /** Sets the bounds this container will occupy after the change */
- public void setEndBounds(@Nullable Rect rect) {
- mEndBounds.set(rect);
+ /** Sets the bounds this container will occupy after the change in screen space */
+ public void setEndAbsBounds(@Nullable Rect rect) {
+ mEndAbsBounds.set(rect);
+ }
+
+ /** Sets the offset of this container from its parent surface */
+ public void setEndRelOffset(int left, int top) {
+ mEndRelOffset.set(left, top);
}
/** @return the container that is changing. May be null if non-remotable (eg. activity) */
@@ -230,8 +271,8 @@ public final class TransitionInfo implements Parcelable {
* is coming into existence.
*/
@NonNull
- public Rect getStartBounds() {
- return mStartBounds;
+ public Rect getStartAbsBounds() {
+ return mStartAbsBounds;
}
/**
@@ -239,8 +280,16 @@ public final class TransitionInfo implements Parcelable {
* is disappearing.
*/
@NonNull
- public Rect getEndBounds() {
- return mEndBounds;
+ public Rect getEndAbsBounds() {
+ return mEndAbsBounds;
+ }
+
+ /**
+ * @return the offset of the container's surface from its parent surface after the change.
+ */
+ @NonNull
+ public Point getEndRelOffset() {
+ return mEndRelOffset;
}
/** @return the leash or surface to animate for this container */
@@ -256,8 +305,9 @@ public final class TransitionInfo implements Parcelable {
dest.writeTypedObject(mParent, flags);
mLeash.writeToParcel(dest, flags);
dest.writeInt(mMode);
- mStartBounds.writeToParcel(dest, flags);
- mEndBounds.writeToParcel(dest, flags);
+ mStartAbsBounds.writeToParcel(dest, flags);
+ mEndAbsBounds.writeToParcel(dest, flags);
+ mEndRelOffset.writeToParcel(dest, flags);
}
@NonNull
@@ -283,8 +333,8 @@ public final class TransitionInfo implements Parcelable {
@Override
public String toString() {
return "{" + mContainer + "(" + mParent + ") leash=" + mLeash
- + " m=" + modeToString(mMode) + " sb=" + mStartBounds
- + " eb=" + mEndBounds + "}";
+ + " m=" + modeToString(mMode) + " sb=" + mStartAbsBounds
+ + " eb=" + mEndAbsBounds + " eo=" + mEndRelOffset + "}";
}
}
}
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index 7a87be35ea98..b9d3df678a91 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -223,7 +223,7 @@ public final class ChangeReporter {
FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER;
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "STATE_" }, value = {
+ @IntDef(prefix = { "STATE_" }, value = {
STATE_UNKNOWN_STATE,
STATE_ENABLED,
STATE_DISABLED,
@@ -233,7 +233,7 @@ public final class ChangeReporter {
}
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "SOURCE_" }, value = {
+ @IntDef(prefix = { "SOURCE_" }, value = {
SOURCE_UNKNOWN_SOURCE,
SOURCE_APP_PROCESS,
SOURCE_SYSTEM_SERVER
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 1fcc6b0a6d55..94e21e5a5965 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -391,16 +391,19 @@ public class ZygoteInit {
SharedLibraryInfo hidlBase = new SharedLibraryInfo(
"/system/framework/android.hidl.base-V1.0-java.jar", null /*packageName*/,
null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
- null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
+ null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
+ false /*isNative*/);
SharedLibraryInfo hidlManager = new SharedLibraryInfo(
"/system/framework/android.hidl.manager-V1.0-java.jar", null /*packageName*/,
null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
- null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
+ null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
+ false /*isNative*/);
SharedLibraryInfo androidTestBase = new SharedLibraryInfo(
"/system/framework/android.test.base.jar", null /*packageName*/,
null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
- null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
+ null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
+ false /*isNative*/);
ApplicationLoaders.getDefault().createAndCacheNonBootclasspathSystemClassLoaders(
new SharedLibraryInfo[]{
@@ -625,8 +628,11 @@ public class ZygoteInit {
/**
* Creates a PathClassLoader for the given class path that is associated with a shared
- * namespace, i.e., this classloader can access platform-private native libraries. The
- * classloader will use java.library.path as the native library path.
+ * namespace, i.e., this classloader can access platform-private native libraries.
+ *
+ * The classloader will add java.library.path to the native library path for the classloader
+ * namespace. Since it includes platform locations like /system/lib, this is only appropriate
+ * for platform code that don't need linker namespace isolation (as opposed to APEXes and apps).
*/
static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
String libraryPath = System.getProperty("java.library.path");
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 33ebe43cb23a..4deb40a0d772 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -25,6 +25,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.Trace;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.CompletionInfo;
@@ -111,6 +112,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
}
}
+ protected Looper getLooper() {
+ synchronized (mMainLooper) {
+ return mMainLooper;
+ }
+ }
+
protected boolean isFinished() {
synchronized (mLock) {
return mFinished;
@@ -259,61 +266,80 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
void executeMessage(Message msg) {
switch (msg.what) {
case DO_GET_TEXT_AFTER_CURSOR: {
- final ICharSequenceResultCallback callback = (ICharSequenceResultCallback) msg.obj;
- final InputConnection ic = getInputConnection();
- final CharSequence result;
- if (ic == null || !isActive()) {
- Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
- result = null;
- } else {
- result = ic.getTextAfterCursor(msg.arg1, msg.arg2);
- }
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getTextAfterCursor");
try {
- callback.onResult(result);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to return the result to getTextAfterCursor()."
+ final ICharSequenceResultCallback callback =
+ (ICharSequenceResultCallback) msg.obj;
+ final InputConnection ic = getInputConnection();
+ final CharSequence result;
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
+ result = null;
+ } else {
+ result = ic.getTextAfterCursor(msg.arg1, msg.arg2);
+ }
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to return the result to getTextAfterCursor()."
+ " result=" + result, e);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
return;
}
case DO_GET_TEXT_BEFORE_CURSOR: {
- final ICharSequenceResultCallback callback = (ICharSequenceResultCallback) msg.obj;
- final InputConnection ic = getInputConnection();
- final CharSequence result;
- if (ic == null || !isActive()) {
- Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
- result = null;
- } else {
- result = ic.getTextBeforeCursor(msg.arg1, msg.arg2);
- }
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getTextBeforeCursor");
try {
- callback.onResult(result);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to return the result to getTextBeforeCursor()."
+ final ICharSequenceResultCallback callback =
+ (ICharSequenceResultCallback) msg.obj;
+ final InputConnection ic = getInputConnection();
+ final CharSequence result;
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
+ result = null;
+ } else {
+ result = ic.getTextBeforeCursor(msg.arg1, msg.arg2);
+ }
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to return the result to getTextBeforeCursor()."
+ " result=" + result, e);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
return;
}
case DO_GET_SELECTED_TEXT: {
- final ICharSequenceResultCallback callback = (ICharSequenceResultCallback) msg.obj;
- final InputConnection ic = getInputConnection();
- final CharSequence result;
- if (ic == null || !isActive()) {
- Log.w(TAG, "getSelectedText on inactive InputConnection");
- result = null;
- } else {
- result = ic.getSelectedText(msg.arg1);
- }
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getSelectedText");
try {
- callback.onResult(result);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to return the result to getSelectedText()."
- + " result=" + result, e);
+ final ICharSequenceResultCallback callback =
+ (ICharSequenceResultCallback) msg.obj;
+ final InputConnection ic = getInputConnection();
+ final CharSequence result;
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "getSelectedText on inactive InputConnection");
+ result = null;
+ } else {
+ result = ic.getSelectedText(msg.arg1);
+ }
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to return the result to getSelectedText()."
+ + " result=" + result, e);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
return;
}
case DO_GET_SURROUNDING_TEXT: {
final SomeArgs args = (SomeArgs) msg.obj;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getSurroundingText");
try {
int beforeLength = (int) args.arg1;
int afterLength = (int) args.arg2;
@@ -335,30 +361,37 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
+ " result=" + result, e);
}
} finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
args.recycle();
}
return;
}
case DO_GET_CURSOR_CAPS_MODE: {
- final IIntResultCallback callback = (IIntResultCallback) msg.obj;
- final InputConnection ic = getInputConnection();
- final int result;
- if (ic == null || !isActive()) {
- Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
- result = 0;
- } else {
- result = ic.getCursorCapsMode(msg.arg1);
- }
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getCursorCapsMode");
try {
- callback.onResult(result);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to return the result to getCursorCapsMode()."
+ final IIntResultCallback callback = (IIntResultCallback) msg.obj;
+ final InputConnection ic = getInputConnection();
+ final int result;
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
+ result = 0;
+ } else {
+ result = ic.getCursorCapsMode(msg.arg1);
+ }
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to return the result to getCursorCapsMode()."
+ " result=" + result, e);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
return;
}
case DO_GET_EXTRACTED_TEXT: {
final SomeArgs args = (SomeArgs) msg.obj;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getExtractedText");
try {
final ExtractedTextRequest request = (ExtractedTextRequest) args.arg1;
final IExtractedTextResultCallback callback =
@@ -378,159 +411,237 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
+ " result=" + result, e);
}
} finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
args.recycle();
}
return;
}
case DO_COMMIT_TEXT: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "commitText on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#commitText");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "commitText on inactive InputConnection");
+ return;
+ }
+ ic.commitText((CharSequence) msg.obj, msg.arg1);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.commitText((CharSequence)msg.obj, msg.arg1);
return;
}
case DO_SET_SELECTION: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "setSelection on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#setSelection");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "setSelection on inactive InputConnection");
+ return;
+ }
+ ic.setSelection(msg.arg1, msg.arg2);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.setSelection(msg.arg1, msg.arg2);
return;
}
case DO_PERFORM_EDITOR_ACTION: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "performEditorAction on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#performEditorAction");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "performEditorAction on inactive InputConnection");
+ return;
+ }
+ ic.performEditorAction(msg.arg1);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.performEditorAction(msg.arg1);
return;
}
case DO_PERFORM_CONTEXT_MENU_ACTION: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "performContextMenuAction on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#performContextMenuAction");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "performContextMenuAction on inactive InputConnection");
+ return;
+ }
+ ic.performContextMenuAction(msg.arg1);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.performContextMenuAction(msg.arg1);
return;
}
case DO_COMMIT_COMPLETION: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "commitCompletion on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#commitCompletion");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "commitCompletion on inactive InputConnection");
+ return;
+ }
+ ic.commitCompletion((CompletionInfo) msg.obj);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.commitCompletion((CompletionInfo)msg.obj);
return;
}
case DO_COMMIT_CORRECTION: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "commitCorrection on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#commitCorrection");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "commitCorrection on inactive InputConnection");
+ return;
+ }
+ ic.commitCorrection((CorrectionInfo) msg.obj);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.commitCorrection((CorrectionInfo)msg.obj);
return;
}
case DO_SET_COMPOSING_TEXT: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "setComposingText on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#setComposingText");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "setComposingText on inactive InputConnection");
+ return;
+ }
+ ic.setComposingText((CharSequence) msg.obj, msg.arg1);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.setComposingText((CharSequence)msg.obj, msg.arg1);
return;
}
case DO_SET_COMPOSING_REGION: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "setComposingRegion on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#setComposingRegion");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "setComposingRegion on inactive InputConnection");
+ return;
+ }
+ ic.setComposingRegion(msg.arg1, msg.arg2);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.setComposingRegion(msg.arg1, msg.arg2);
return;
}
case DO_FINISH_COMPOSING_TEXT: {
- if (isFinished()) {
- // In this case, #finishComposingText() is guaranteed to be called already.
- // There should be no negative impact if we ignore this call silently.
- if (DEBUG) {
- Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#finishComposingText");
+ try {
+ if (isFinished()) {
+ // In this case, #finishComposingText() is guaranteed to be called already.
+ // There should be no negative impact if we ignore this call silently.
+ if (DEBUG) {
+ Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
+ }
+ return;
}
- return;
- }
- InputConnection ic = getInputConnection();
- // Note we do NOT check isActive() here, because this is safe
- // for an IME to call at any time, and we need to allow it
- // through to clean up our state after the IME has switched to
- // another client.
- if (ic == null) {
- Log.w(TAG, "finishComposingText on inactive InputConnection");
- return;
+ InputConnection ic = getInputConnection();
+ // Note we do NOT check isActive() here, because this is safe
+ // for an IME to call at any time, and we need to allow it
+ // through to clean up our state after the IME has switched to
+ // another client.
+ if (ic == null) {
+ Log.w(TAG, "finishComposingText on inactive InputConnection");
+ return;
+ }
+ ic.finishComposingText();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.finishComposingText();
return;
}
case DO_SEND_KEY_EVENT: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "sendKeyEvent on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#sendKeyEvent");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "sendKeyEvent on inactive InputConnection");
+ return;
+ }
+ ic.sendKeyEvent((KeyEvent) msg.obj);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.sendKeyEvent((KeyEvent)msg.obj);
return;
}
case DO_CLEAR_META_KEY_STATES: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#clearMetaKeyStates");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
+ return;
+ }
+ ic.clearMetaKeyStates(msg.arg1);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.clearMetaKeyStates(msg.arg1);
return;
}
case DO_DELETE_SURROUNDING_TEXT: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#deleteSurroundingText");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
+ return;
+ }
+ ic.deleteSurroundingText(msg.arg1, msg.arg2);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.deleteSurroundingText(msg.arg1, msg.arg2);
return;
}
case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT,
+ "InputConnection#deleteSurroundingTextInCodePoints");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
+ return;
+ }
+ ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
return;
}
case DO_BEGIN_BATCH_EDIT: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "beginBatchEdit on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#beginBatchEdit");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "beginBatchEdit on inactive InputConnection");
+ return;
+ }
+ ic.beginBatchEdit();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.beginBatchEdit();
return;
}
case DO_END_BATCH_EDIT: {
- InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
- Log.w(TAG, "endBatchEdit on inactive InputConnection");
- return;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#endBatchEdit");
+ try {
+ InputConnection ic = getInputConnection();
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "endBatchEdit on inactive InputConnection");
+ return;
+ }
+ ic.endBatchEdit();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
- ic.endBatchEdit();
return;
}
case DO_PERFORM_PRIVATE_COMMAND: {
final SomeArgs args = (SomeArgs) msg.obj;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#performPrivateCommand");
try {
final String action = (String) args.arg1;
final Bundle data = (Bundle) args.arg2;
@@ -541,25 +652,31 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
}
ic.performPrivateCommand(action, data);
} finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
args.recycle();
}
return;
}
case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
- final IIntResultCallback callback = (IIntResultCallback) msg.obj;
- final InputConnection ic = getInputConnection();
- final boolean result;
- if (ic == null || !isActive()) {
- Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
- result = false;
- } else {
- result = ic.requestCursorUpdates(msg.arg1);
- }
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#requestCursorUpdates");
try {
- callback.onResult(result ? 1 : 0);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to return the result to requestCursorUpdates()."
- + " result=" + result, e);
+ final IIntResultCallback callback = (IIntResultCallback) msg.obj;
+ final InputConnection ic = getInputConnection();
+ final boolean result;
+ if (ic == null || !isActive()) {
+ Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
+ result = false;
+ } else {
+ result = ic.requestCursorUpdates(msg.arg1);
+ }
+ try {
+ callback.onResult(result ? 1 : 0);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to return the result to requestCursorUpdates()."
+ + " result=" + result, e);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
return;
}
@@ -571,6 +688,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
if (isFinished()) {
return;
}
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#closeConnection");
try {
InputConnection ic = getInputConnection();
// Note we do NOT check isActive() here, because this is safe
@@ -590,12 +708,14 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
mInputConnection = null;
mFinished = true;
}
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
return;
}
case DO_COMMIT_CONTENT: {
final int flags = msg.arg1;
SomeArgs args = (SomeArgs) msg.obj;
+ Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#commitContent");
try {
final IIntResultCallback callback = (IIntResultCallback) args.arg3;
final InputConnection ic = getInputConnection();
@@ -620,6 +740,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
+ " result=" + result, e);
}
} finally {
+ Trace.traceEnd(Trace.TRACE_TAG_INPUT);
args.recycle();
}
return;
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index 1145f5183206..ec9a0a2f4801 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -25,7 +25,7 @@ import com.android.internal.view.InputBindResult;
oneway interface IInputMethodClient {
void onBindMethod(in InputBindResult res);
void onUnbindMethod(int sequence, int unbindReason);
- void setActive(boolean active, boolean fullscreen);
+ void setActive(boolean active, boolean fullscreen, boolean reportToImeController);
void scheduleStartInputIfNecessary(boolean fullscreen);
void reportFullscreenMode(boolean fullscreen);
void applyImeVisibility(boolean setVisible);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 844c56bd3529..33abbe82c109 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -79,4 +79,9 @@ interface IInputMethodManager {
void removeImeSurfaceFromWindow(in IBinder windowToken);
void startProtoDump(in byte[] protoDump, int source, String where);
boolean isImeTraceEnabled();
+
+ // Starts an ime trace.
+ void startImeTrace();
+ // Stops an ime trace.
+ void stopImeTrace();
}
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index 0319e3637384..c6afd78ec04b 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -52,4 +52,6 @@ oneway interface IInputMethodSession {
void notifyImeHidden();
void removeImeSurface();
+
+ void finishInput();
}
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index ff3543c837eb..d30d662806d4 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -16,21 +16,36 @@
package com.android.internal.widget;
+import static android.view.inputmethod.InputConnectionProto.CURSOR_CAPS_MODE;
+import static android.view.inputmethod.InputConnectionProto.EDITABLE_TEXT;
+import static android.view.inputmethod.InputConnectionProto.SELECTED_TEXT;
+import static android.view.inputmethod.InputConnectionProto.SELECTED_TEXT_END;
+import static android.view.inputmethod.InputConnectionProto.SELECTED_TEXT_START;
+
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.text.Editable;
+import android.text.Selection;
import android.text.method.KeyListener;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
+import android.view.inputmethod.DumpableInputConnection;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.widget.TextView;
-public class EditableInputConnection extends BaseInputConnection {
+/**
+ * Base class for an editable InputConnection instance. This is created by {@link TextView} or
+ * {@link EditText}.
+ */
+public class EditableInputConnection extends BaseInputConnection
+ implements DumpableInputConnection {
private static final boolean DEBUG = false;
+ private static final boolean DUMP_TEXT = false;
private static final String TAG = "EditableInputConnection";
private final TextView mTextView;
@@ -222,4 +237,28 @@ public class EditableInputConnection extends BaseInputConnection {
}
return true;
}
+
+ @Override
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ CharSequence editableText = mTextView.getText();
+ CharSequence selectedText = getSelectedText(0 /* flags */);
+ if (DUMP_TEXT) {
+ if (editableText != null) {
+ proto.write(EDITABLE_TEXT, editableText.toString());
+ }
+ if (selectedText != null) {
+ proto.write(SELECTED_TEXT, selectedText.toString());
+ }
+ }
+ final Editable content = getEditable();
+ if (content != null) {
+ int start = Selection.getSelectionStart(content);
+ int end = Selection.getSelectionEnd(content);
+ proto.write(SELECTED_TEXT_START, start);
+ proto.write(SELECTED_TEXT_END, end);
+ }
+ proto.write(CURSOR_CAPS_MODE, getCursorCapsMode(0));
+ proto.end(token);
+ }
}
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 58817a8a48a9..514e0b8e0ded 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -61,12 +61,17 @@ import android.widget.PopupWindow;
import android.widget.TextView;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
/**
@@ -93,7 +98,6 @@ public final class FloatingToolbar {
private final Rect mPreviousContentRect = new Rect();
private Menu mMenu;
- private List<MenuItem> mShowingMenuItems = new ArrayList<>();
private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER;
private int mSuggestedWidth;
@@ -274,10 +278,11 @@ public final class FloatingToolbar {
private void doShow() {
List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu);
menuItems.sort(mMenuItemComparator);
- if (!isCurrentlyShowing(menuItems) || mWidthChanged) {
+ if (mPopup.isLayoutRequired(menuItems) || mWidthChanged) {
mPopup.dismiss();
mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
- mShowingMenuItems = menuItems;
+ } else {
+ mPopup.updateMenuItems(menuItems, mMenuItemClickListener);
}
if (!mPopup.isShowing()) {
mPopup.show(mContentRect);
@@ -289,33 +294,10 @@ public final class FloatingToolbar {
}
/**
- * Returns true if this floating toolbar is currently showing the specified menu items.
- */
- private boolean isCurrentlyShowing(List<MenuItem> menuItems) {
- if (mShowingMenuItems == null || menuItems.size() != mShowingMenuItems.size()) {
- return false;
- }
-
- final int size = menuItems.size();
- for (int i = 0; i < size; i++) {
- final MenuItem menuItem = menuItems.get(i);
- final MenuItem showingItem = mShowingMenuItems.get(i);
- if (menuItem.getItemId() != showingItem.getItemId()
- || !TextUtils.equals(menuItem.getTitle(), showingItem.getTitle())
- || !Objects.equals(menuItem.getIcon(), showingItem.getIcon())
- || menuItem.getGroupId() != showingItem.getGroupId()) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
* Returns the visible and enabled menu items in the specified menu.
* This method is recursive.
*/
- private List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) {
+ private static List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) {
List<MenuItem> menuItems = new ArrayList<>();
for (int i = 0; (menu != null) && (i < menu.size()); i++) {
MenuItem menuItem = menu.getItem(i);
@@ -427,17 +409,25 @@ public final class FloatingToolbar {
private Size mOverflowPanelSize; // Should be null when there is no overflow.
private Size mMainPanelSize;
- /* Item click listeners */
+ /* Menu items and click listeners */
+ private final Map<MenuItemRepr, MenuItem> mMenuItems = new LinkedHashMap<>();
private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
private final View.OnClickListener mMenuItemButtonOnClickListener =
new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (v.getTag() instanceof MenuItem) {
- if (mOnMenuItemClickListener != null) {
- mOnMenuItemClickListener.onMenuItemClick((MenuItem) v.getTag());
- }
+ if (mOnMenuItemClickListener == null) {
+ return;
+ }
+ final Object tag = v.getTag();
+ if (!(tag instanceof MenuItemRepr)) {
+ return;
}
+ final MenuItem menuItem = mMenuItems.get((MenuItemRepr) tag);
+ if (menuItem == null) {
+ return;
+ }
+ mOnMenuItemClickListener.onMenuItemClick(menuItem);
}
};
@@ -558,9 +548,9 @@ public final class FloatingToolbar {
List<MenuItem> menuItems,
MenuItem.OnMenuItemClickListener menuItemClickListener,
int suggestedWidth) {
- mOnMenuItemClickListener = menuItemClickListener;
cancelOverflowAnimations();
clearPanels();
+ updateMenuItems(menuItems, menuItemClickListener);
menuItems = layoutMainPanelItems(menuItems, getAdjustedToolbarWidth(suggestedWidth));
if (!menuItems.isEmpty()) {
// Add remaining items to the overflow.
@@ -570,6 +560,28 @@ public final class FloatingToolbar {
}
/**
+ * Updates the popup's menu items without rebuilding the widget.
+ * Use in place of layoutMenuItems() when the popup's views need not be reconstructed.
+ *
+ * @see isLayoutRequired(List<MenuItem>)
+ */
+ public void updateMenuItems(
+ List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener) {
+ mMenuItems.clear();
+ for (MenuItem menuItem : menuItems) {
+ mMenuItems.put(MenuItemRepr.of(menuItem), menuItem);
+ }
+ mOnMenuItemClickListener = menuItemClickListener;
+ }
+
+ /**
+ * Returns true if this popup needs a relayout to properly render the specified menu items.
+ */
+ public boolean isLayoutRequired(List<MenuItem> menuItems) {
+ return !MenuItemRepr.reprEquals(menuItems, mMenuItems.values());
+ }
+
+ /**
* Shows this popup at the specified coordinates.
* The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
*/
@@ -1374,7 +1386,7 @@ public final class FloatingToolbar {
}
private void setButtonTagAndClickListener(View menuItemButton, MenuItem menuItem) {
- menuItemButton.setTag(menuItem);
+ menuItemButton.setTag(MenuItemRepr.of(menuItem));
menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener);
}
@@ -1656,6 +1668,85 @@ public final class FloatingToolbar {
}
/**
+ * Represents the identity of a MenuItem that is rendered in a FloatingToolbarPopup.
+ */
+ @VisibleForTesting
+ public static final class MenuItemRepr {
+
+ public final int itemId;
+ public final int groupId;
+ @Nullable public final String title;
+ @Nullable private final Drawable mIcon;
+
+ private MenuItemRepr(
+ int itemId, int groupId, @Nullable CharSequence title, @Nullable Drawable icon) {
+ this.itemId = itemId;
+ this.groupId = groupId;
+ this.title = (title == null) ? null : title.toString();
+ mIcon = icon;
+ }
+
+ /**
+ * Creates an instance of MenuItemRepr for the specified menu item.
+ */
+ public static MenuItemRepr of(MenuItem menuItem) {
+ return new MenuItemRepr(
+ menuItem.getItemId(),
+ menuItem.getGroupId(),
+ menuItem.getTitle(),
+ menuItem.getIcon());
+ }
+
+ /**
+ * Returns this object's hashcode.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(itemId, groupId, title, mIcon);
+ }
+
+ /**
+ * Returns true if this object is the same as the specified object.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof MenuItemRepr)) {
+ return false;
+ }
+ final MenuItemRepr other = (MenuItemRepr) o;
+ return itemId == other.itemId
+ && groupId == other.groupId
+ && TextUtils.equals(title, other.title)
+ // Many Drawables (icons) do not implement equals(). Using equals() here instead
+ // of reference comparisons in case a Drawable subclass implements equals().
+ && Objects.equals(mIcon, other.mIcon);
+ }
+
+ /**
+ * Returns true if the two menu item collections are the same based on MenuItemRepr.
+ */
+ public static boolean reprEquals(
+ Collection<MenuItem> menuItems1, Collection<MenuItem> menuItems2) {
+ if (menuItems1.size() != menuItems2.size()) {
+ return false;
+ }
+
+ final Iterator<MenuItem> menuItems2Iter = menuItems2.iterator();
+ for (MenuItem menuItem1 : menuItems1) {
+ final MenuItem menuItem2 = menuItems2Iter.next();
+ if (!MenuItemRepr.of(menuItem1).equals(MenuItemRepr.of(menuItem2))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ /**
* Creates and returns a menu button for the specified menu item.
*/
private static View createMenuItemButton(
diff --git a/core/proto/Android.bp b/core/proto/Android.bp
deleted file mode 100644
index 3b891d6b4947..000000000000
--- a/core/proto/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2018 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.
-
-// C++ library for Bluetooth platform wide protobuf definitions
-cc_library_static {
- name: "libbt-platform-protos-lite",
- host_supported: true,
- proto: {
- export_proto_headers: true,
- type: "lite",
- },
- srcs: [
- "android/bluetooth/a2dp/enums.proto",
- "android/bluetooth/enums.proto",
- "android/bluetooth/hci/enums.proto",
- "android/bluetooth/hfp/enums.proto",
- "android/bluetooth/smp/enums.proto",
- ],
-}
diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto
deleted file mode 100644
index 722194b322c6..000000000000
--- a/core/proto/android/app/enums.proto
+++ /dev/null
@@ -1,215 +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.
- */
-
-syntax = "proto2";
-
-package android.app;
-
-option java_outer_classname = "AppProtoEnums";
-option java_multiple_files = true;
-
-// ActivityManagerInternal.java's APP_TRANSITION reasons.
-enum AppTransitionReasonEnum {
- APP_TRANSITION_REASON_UNKNOWN = 0;
- // The transition was started because we drew the splash screen.
- APP_TRANSITION_SPLASH_SCREEN = 1;
- // The transition was started because we all app windows were drawn.
- APP_TRANSITION_WINDOWS_DRAWN = 2;
- // The transition was started because of a timeout.
- APP_TRANSITION_TIMEOUT = 3;
- // The transition was started because of a we drew a task snapshot.
- APP_TRANSITION_SNAPSHOT = 4;
- // The transition was started because it was a recents animation and we only needed to wait on
- // the wallpaper.
- APP_TRANSITION_RECENTS_ANIM = 5;
-}
-
-// ActivityManager.java PROCESS_STATEs
-// Next tag: 1021
-enum ProcessStateEnum {
- // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values
- // here are completely fixed and arbitrary. Order is irrelevant.
- // No attempt need be made to keep them in sync.
- // The values here must not be modified. Any new process states can be appended to the end.
-
- // Process state that is unknown to this proto file (i.e. is not mapped
- // by ActivityManager.processStateAmToProto()). Can only happen if there's a bug in the mapping.
- PROCESS_STATE_UNKNOWN_TO_PROTO = 998;
- // Not a real process state.
- PROCESS_STATE_UNKNOWN = 999;
- // Process is a persistent system process.
- PROCESS_STATE_PERSISTENT = 1000;
- // Process is a persistent system process and is doing UI.
- PROCESS_STATE_PERSISTENT_UI = 1001;
- // Process is hosting the current top activities. Note that this covers
- // all activities that are visible to the user.
- PROCESS_STATE_TOP = 1002;
- // Process is bound to a TOP app.
- PROCESS_STATE_BOUND_TOP = 1020;
- // Process is hosting a foreground service.
- PROCESS_STATE_FOREGROUND_SERVICE = 1003;
- // Process is hosting a service bound by the system or another foreground app.
- PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004;
- // Process is important to the user, and something they are aware of.
- PROCESS_STATE_IMPORTANT_FOREGROUND = 1005;
- // Process is important to the user, but not something they are aware of.
- PROCESS_STATE_IMPORTANT_BACKGROUND = 1006;
- // Process is in the background transient so we will try to keep running.
- PROCESS_STATE_TRANSIENT_BACKGROUND = 1007;
- // Process is in the background running a backup/restore operation.
- PROCESS_STATE_BACKUP = 1008;
- // Process is in the background running a service. Unlike oom_adj, this
- // level is used for both the normal running in background state and the
- // executing operations state.
- PROCESS_STATE_SERVICE = 1009;
- // Process is in the background running a receiver. Note that from the
- // perspective of oom_adj, receivers run at a higher foreground level, but
- // for our prioritization here that is not necessary and putting them
- // below services means many fewer changes in some process states as they
- // receive broadcasts.
- PROCESS_STATE_RECEIVER = 1010;
- // Same as PROCESS_STATE_TOP but while device is sleeping.
- PROCESS_STATE_TOP_SLEEPING = 1011;
- // Process is in the background, but it can't restore its state so we want
- // to try to avoid killing it.
- PROCESS_STATE_HEAVY_WEIGHT = 1012;
- // Process is in the background but hosts the home activity.
- PROCESS_STATE_HOME = 1013;
- // Process is in the background but hosts the last shown activity.
- PROCESS_STATE_LAST_ACTIVITY = 1014;
- // Process is being cached for later use and contains activities.
- PROCESS_STATE_CACHED_ACTIVITY = 1015;
- // Process is being cached for later use and is a client of another cached
- // process that contains activities.
- PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 1016;
- // Process is being cached for later use and has an activity that corresponds
- // to an existing recent task.
- PROCESS_STATE_CACHED_RECENT = 1017;
- // Process is being cached for later use and is empty.
- PROCESS_STATE_CACHED_EMPTY = 1018;
- // Process does not exist.
- PROCESS_STATE_NONEXISTENT = 1019;
-}
-
-// AppOpsManager.java - operation ids for logging
-enum AppOpEnum {
- APP_OP_NONE = -1;
- APP_OP_COARSE_LOCATION = 0;
- APP_OP_FINE_LOCATION = 1;
- APP_OP_GPS = 2;
- APP_OP_VIBRATE = 3;
- APP_OP_READ_CONTACTS = 4;
- APP_OP_WRITE_CONTACTS = 5;
- APP_OP_READ_CALL_LOG = 6;
- APP_OP_WRITE_CALL_LOG = 7;
- APP_OP_READ_CALENDAR = 8;
- APP_OP_WRITE_CALENDAR = 9;
- APP_OP_WIFI_SCAN = 10;
- APP_OP_POST_NOTIFICATION = 11;
- APP_OP_NEIGHBORING_CELLS = 12;
- APP_OP_CALL_PHONE = 13;
- APP_OP_READ_SMS = 14;
- APP_OP_WRITE_SMS = 15;
- APP_OP_RECEIVE_SMS = 16;
- APP_OP_RECEIVE_EMERGENCY_SMS = 17;
- APP_OP_RECEIVE_MMS = 18;
- APP_OP_RECEIVE_WAP_PUSH = 19;
- APP_OP_SEND_SMS = 20;
- APP_OP_READ_ICC_SMS = 21;
- APP_OP_WRITE_ICC_SMS = 22;
- APP_OP_WRITE_SETTINGS = 23;
- APP_OP_SYSTEM_ALERT_WINDOW = 24;
- APP_OP_ACCESS_NOTIFICATIONS = 25;
- APP_OP_CAMERA = 26;
- APP_OP_RECORD_AUDIO = 27;
- APP_OP_PLAY_AUDIO = 28;
- APP_OP_READ_CLIPBOARD = 29;
- APP_OP_WRITE_CLIPBOARD = 30;
- APP_OP_TAKE_MEDIA_BUTTONS = 31;
- APP_OP_TAKE_AUDIO_FOCUS = 32;
- APP_OP_AUDIO_MASTER_VOLUME = 33;
- APP_OP_AUDIO_VOICE_VOLUME = 34;
- APP_OP_AUDIO_RING_VOLUME = 35;
- APP_OP_AUDIO_MEDIA_VOLUME = 36;
- APP_OP_AUDIO_ALARM_VOLUME = 37;
- APP_OP_AUDIO_NOTIFICATION_VOLUME = 38;
- APP_OP_AUDIO_BLUETOOTH_VOLUME = 39;
- APP_OP_WAKE_LOCK = 40;
- APP_OP_MONITOR_LOCATION = 41;
- APP_OP_MONITOR_HIGH_POWER_LOCATION = 42;
- APP_OP_GET_USAGE_STATS = 43;
- APP_OP_MUTE_MICROPHONE = 44;
- APP_OP_TOAST_WINDOW = 45;
- APP_OP_PROJECT_MEDIA = 46;
- APP_OP_ACTIVATE_VPN = 47;
- APP_OP_WRITE_WALLPAPER = 48;
- APP_OP_ASSIST_STRUCTURE = 49;
- APP_OP_ASSIST_SCREENSHOT = 50;
- APP_OP_READ_PHONE_STATE = 51;
- APP_OP_ADD_VOICEMAIL = 52;
- APP_OP_USE_SIP = 53;
- APP_OP_PROCESS_OUTGOING_CALLS = 54;
- APP_OP_USE_FINGERPRINT = 55;
- APP_OP_BODY_SENSORS = 56;
- APP_OP_READ_CELL_BROADCASTS = 57;
- APP_OP_MOCK_LOCATION = 58;
- APP_OP_READ_EXTERNAL_STORAGE = 59;
- APP_OP_WRITE_EXTERNAL_STORAGE = 60;
- APP_OP_TURN_SCREEN_ON = 61;
- APP_OP_GET_ACCOUNTS = 62;
- APP_OP_RUN_IN_BACKGROUND = 63;
- APP_OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
- APP_OP_READ_PHONE_NUMBERS = 65;
- APP_OP_REQUEST_INSTALL_PACKAGES = 66;
- APP_OP_PICTURE_IN_PICTURE = 67;
- APP_OP_INSTANT_APP_START_FOREGROUND = 68;
- APP_OP_ANSWER_PHONE_CALLS = 69;
- APP_OP_RUN_ANY_IN_BACKGROUND = 70;
- APP_OP_CHANGE_WIFI_STATE = 71;
- APP_OP_REQUEST_DELETE_PACKAGES = 72;
- APP_OP_BIND_ACCESSIBILITY_SERVICE = 73;
- APP_OP_ACCEPT_HANDOVER = 74;
- APP_OP_MANAGE_IPSEC_TUNNELS = 75;
- APP_OP_START_FOREGROUND = 76;
- APP_OP_BLUETOOTH_SCAN = 77;
- APP_OP_USE_BIOMETRIC = 78;
- APP_OP_ACTIVITY_RECOGNITION = 79;
- APP_OP_SMS_FINANCIAL_TRANSACTIONS = 80;
- APP_OP_READ_MEDIA_AUDIO = 81;
- APP_OP_WRITE_MEDIA_AUDIO = 82;
- APP_OP_READ_MEDIA_VIDEO = 83;
- APP_OP_WRITE_MEDIA_VIDEO = 84;
- APP_OP_READ_MEDIA_IMAGES = 85;
- APP_OP_WRITE_MEDIA_IMAGES = 86;
- APP_OP_LEGACY_STORAGE = 87;
- APP_OP_ACCESS_ACCESSIBILITY = 88;
- APP_OP_READ_DEVICE_IDENTIFIERS = 89;
- APP_OP_ACCESS_MEDIA_LOCATION = 90;
- APP_OP_QUERY_ALL_PACKAGES = 91;
- APP_OP_MANAGE_EXTERNAL_STORAGE = 92;
- APP_OP_INTERACT_ACROSS_PROFILES = 93;
- APP_OP_ACTIVATE_PLATFORM_VPN = 94;
- APP_OP_LOADER_USAGE_STATS = 95;
- APP_OP_DEPRECATED_1 = 96 [deprecated = true];
- APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
- APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
- APP_OP_NO_ISOLATED_STORAGE = 99;
- APP_OP_PHONE_CALL_MICROPHONE = 100;
- APP_OP_PHONE_CALL_CAMERA = 101;
- APP_OP_RECORD_AUDIO_HOTWORD = 102;
- APP_OP_MANAGE_ONGOING_CALLS = 103;
- APP_OP_MANAGE_CREDENTIALS = 104;
-}
diff --git a/core/proto/android/app/job/enums.proto b/core/proto/android/app/job/enums.proto
deleted file mode 100644
index 41863bbbfbf1..000000000000
--- a/core/proto/android/app/job/enums.proto
+++ /dev/null
@@ -1,38 +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.
- */
-
-syntax = "proto2";
-
-package android.app.job;
-
-// This file is for JobScheduler enums inside the app directory. If you're
-// adding enums for system-server-side code, use the file in
-// frameworks/base/core/proto/android/server/job.
-option java_outer_classname = "JobProtoEnums";
-option java_multiple_files = true;
-
-// Reasons a job is stopped.
-// Primarily used in android.app.job.JobParameters.java.
-enum StopReasonEnum {
- STOP_REASON_UNKNOWN = -1;
- STOP_REASON_CANCELLED = 0;
- STOP_REASON_CONSTRAINTS_NOT_SATISFIED = 1;
- STOP_REASON_PREEMPT = 2;
- STOP_REASON_TIMEOUT = 3;
- STOP_REASON_DEVICE_IDLE = 4;
- STOP_REASON_DEVICE_THERMAL = 5;
- STOP_REASON_RESTRICTED_BUCKET = 6;
-}
diff --git a/core/proto/android/app/media_output_enum.proto b/core/proto/android/app/media_output_enum.proto
deleted file mode 100644
index 0d42fb77025a..000000000000
--- a/core/proto/android/app/media_output_enum.proto
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.settings.mediaoutput;
-option java_multiple_files = true;
-
-/**
- * The medium type specified in an output switching operation.
- */
-enum MediumType {
- UNKNOWN_TYPE = 0;
- BUILTIN_SPEAKER = 1;
- WIRED_3POINT5_MM_AUDIO = 100;
- WIRED_3POINT5_MM_HEADSET = 101;
- WIRED_3POINT5_MM_HEADPHONES = 102;
- USB_C_AUDIO = 200;
- USB_C_DEVICE = 201;
- USB_C_HEADSET = 202;
- USB_C_ACCESSORY = 203;
- USB_C_DOCK = 204;
- USB_C_HDMI = 205;
- BLUETOOTH = 300;
- BLUETOOTH_HEARING_AID = 301;
- BLUETOOTH_A2DP = 302;
- REMOTE_SINGLE = 400;
- REMOTE_TV = 401;
- REMOTE_SPEAKER = 402;
- REMOTE_GROUP = 500;
- REMOTE_DYNAMIC_GROUP = 501;
-};
-
-/**
- * The result of an output switching operation.
- */
-enum SwitchResult {
- ERROR = 0;
- OK = 1;
-};
-
-/**
- * The sub result of an output switching operation.
- */
-enum SubResult {
- UNKNOWN_ERROR = 0;
- NO_ERROR = 1;
- REJECTED = 2;
- NETWORK_ERROR = 3;
- ROUTE_NOT_AVAILABLE = 4;
- INVALID_COMMAND = 5;
-}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
deleted file mode 100644
index a2a7649645f5..000000000000
--- a/core/proto/android/app/settings_enums.proto
+++ /dev/null
@@ -1,2794 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.settings;
-option java_multiple_files = true;
-
-/**
- * The action performed in this event
- */
-enum Action {
- ACTION_UNKNOWN = 0;
- PAGE_VISIBLE = 1;
- PAGE_HIDE = 2;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network
- // SUBTYPE: true if connecting to a saved network, false if not
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_CONNECT = 135;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Forget network
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_FORGET = 137;
-
- // ACTION: Settings > Wi-Fi > Toggle off
- // SUBTYPE: true if connected to network before toggle, false if not
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_OFF = 138;
-
- // ACTION: Settings > Wi-Fi > Toggle on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_WIFI_ON = 139;
-
- // ACTION: Settings > Bluetooth > Overflow > Rename this device
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_BLUETOOTH_RENAME = 161;
-
- // ACTION: Settings > Bluetooth > Overflow > Show received files
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_BLUETOOTH_FILES = 162;
-
- // ACTION: DND Settings > Priority only allows > Reminder toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_REMINDERS = 167;
-
- // ACTION: DND Settings > Priority only allows > Event toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_EVENTS = 168;
-
- // ACTION: DND Settings > Priority only allows > Messages
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_MESSAGES = 169;
-
- // ACTION: DND Settings > Priority only allows > Calls
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_CALLS = 170;
-
- // ACTION: DND Settings > Priority only allows > Repeat callers toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
-
- // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_DELETE_RULE_OK = 175;
-
- // ACTION: Settings > More > Airplane mode toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_AIRPLANE_TOGGLE = 177;
-
- // ACTION: Settings > Data usage > Cellular data toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_CELL_DATA_TOGGLE = 178;
-
- // ACTION: Settings > Display > When device is rotated
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ROTATION_LOCK = 203;
-
- // OPEN: Settings > Search > Perform search
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_SEARCH_RESULTS = 226;
-
- // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_FINGERPRINT_DELETE = 253;
-
- // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_FINGERPRINT_RENAME = 254;
-
- // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report
- // CATEGORY: SETTINGS
- // OS: N
- // Interactive bug report initiated from Settings.
- ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294;
-
- // ACTION: Settings -> Developer Options -> Take bug report -> Full report
- // CATEGORY: SETTINGS
- // OS: N
- // Interactive bug report initiated from Settings.
- ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295;
-
- // click on collapsed conditional or clicks expand button
- ACTION_SETTINGS_CONDITION_EXPAND = 373;
-
- // click main area of expanded conditional
- ACTION_SETTINGS_CONDITION_CLICK = 375;
-
- // click a direct button on expanded conditional
- ACTION_SETTINGS_CONDITION_BUTTON = 376;
-
- // Action: user enable / disabled data saver using Settings
- // OPEN: Settings -> Data Usage -> Data saver -> On/off toggle
- // VALUE: 1 for enabled, 0 for disabled
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_MODE = 394;
-
- // User whitelisted an app for Data Saver mode; action pass package name of app
- // Action: user enable / disabled data saver using Settings
- // OPEN: Settings -> Data Usage -> Data saver -> Unrestricted data access > APP toggle turned on
- // or
- // Settings -> Apps -> APP -> Data usage -> Unrestricted data usage toggle turned on
- // VALUE: package name of APP
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_WHITELIST = 395;
-
- // User blacklisted an app for Data Saver mode; action pass package name of app
- // OPEN: Settings -> Apps -> APP -> Data usage -> Background data toggle turned off
- // VALUE: package name of APP
- // CATEGORY: SETTINGS
- // OS: N
- ACTION_DATA_SAVER_BLACKLIST = 396;
-
- // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager
- // SUBTYPE: false is off, true is on
- ACTION_TOGGLE_STORAGE_MANAGER = 489;
-
- // OPEN: Settings > Display -> Ambient Display
- // CATEGORY: SETTINGS
- ACTION_AMBIENT_DISPLAY = 495;
-
- // ACTION: Allow Battery optimization for an app
- APP_SPECIAL_PERMISSION_BATTERY_ALLOW = 764;
-
- // ACTION: Deny Battery optimization for an app
- APP_SPECIAL_PERMISSION_BATTERY_DENY = 765;
-
- // ACTION: Enable Device Admin app
- APP_SPECIAL_PERMISSION_ADMIN_ALLOW = 766;
-
- // ACTION: Disable Device Admin app
- APP_SPECIAL_PERMISSION_ADMIN_DENY = 767;
-
- // ACTION: Allow "Do Not Disturb access" for an app
- APP_SPECIAL_PERMISSION_DND_ALLOW = 768;
-
- // ACTION: Deny "Do Not Disturb access" for an app
- APP_SPECIAL_PERMISSION_DND_DENY = 769;
-
- // ACTION: Allow "Draw over other apps" for an app
- APP_SPECIAL_PERMISSION_APPDRAW_ALLOW = 770;
-
- // ACTION: Deny "Display over other apps" for an app
- APP_SPECIAL_PERMISSION_APPDRAW_DENY = 771;
-
- // ACTION: Allow "VR helper services" for an app
- APP_SPECIAL_PERMISSION_VRHELPER_ALLOW = 772;
-
- // ACTION: Deny "VR helper services" for an app
- APP_SPECIAL_PERMISSION_VRHELPER_DENY = 773;
-
- // ACTION: Allow "Modify system settings" for an app
- APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_ALLOW = 774;
-
- // ACTION: Deny "Modify system settings" for an app
- APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_DENY = 775;
-
- // ACTION: Allow "Notification access" for an app
- APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW = 776;
-
- // ACTION: Deny "Notification access" for an app
- APP_SPECIAL_PERMISSION_NOTIVIEW_DENY = 777;
-
- // ACTION: "Premium SMS access" for an app - "ask user" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_ASK = 778;
-
- // ACTION: "Premium SMS access" for an app - "never allow" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_DENY = 779;
-
- // ACTION: "Premium SMS access" for an app - "always allow" option
- APP_SPECIAL_PERMISSION_PREMIUM_SMS_ALWAYS_ALLOW = 780;
-
- // ACTION: Allow "Unrestricted data access" for an app
- APP_SPECIAL_PERMISSION_UNL_DATA_ALLOW = 781;
-
- // ACTION: Deny "Unrestricted data access" for an app
- APP_SPECIAL_PERMISSION_UNL_DATA_DENY = 782;
-
- // ACTION: Allow "Usage access" for an app
- APP_SPECIAL_PERMISSION_USAGE_VIEW_ALLOW = 783;
-
- // ACTION: Deny "Usage access" for an app
- APP_SPECIAL_PERMISSION_USAGE_VIEW_DENY = 784;
-
- // ACTION: "Force stop" action on an app
- ACTION_APP_FORCE_STOP = 807;
-
- // ACTION: Allow "Enable picture-in-picture" for an app
- APP_PICTURE_IN_PICTURE_ALLOW = 813;
-
- // ACTION: Create a Settings shortcut item.
- ACTION_SETTINGS_CREATE_SHORTCUT = 829;
-
- // ACTION: A tile in Settings information architecture is clicked
- ACTION_SETTINGS_TILE_CLICK = 830;
-
- // ACTION: Settings advanced button is expanded
- ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND = 834;
-
- // ACTION: Deny "Enable picture-in-picture" for an app
- APP_PICTURE_IN_PICTURE_DENY = 814;
-
- // ACTION: Settings -> Display -> Theme
- ACTION_THEME = 816;
-
- // ACTION: Settings > About device > Build number
- ACTION_SETTINGS_BUILD_NUMBER_PREF = 847;
-
- // ACTION: Settings > Battery > Menu > Optimization
- ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION = 851;
-
- // ACTION: Settings > Battery > Menu > Apps Toggle
- ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE = 852;
-
- // ACTION: Settings > Any preference is changed
- ACTION_SETTINGS_PREFERENCE_CHANGE = 853;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Available devices
- ACTION_SETTINGS_BLUETOOTH_PAIR = 866;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Paired devices
- ACTION_SETTINGS_BLUETOOTH_CONNECT = 867;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Connected device
- ACTION_SETTINGS_BLUETOOTH_DISCONNECT = 868;
-
- // ACTION: Settings > Connected devices > Bluetooth -> Error dialog
- ACTION_SETTINGS_BLUETOOTH_CONNECT_ERROR = 869;
-
- // ACTION: Settings > Connected devices > Bluetooth master switch Toggle
- ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870;
-
- // ACTION: Settings > App detail > Uninstall
- ACTION_SETTINGS_UNINSTALL_APP = 872;
-
- // ACTION: Settings > App detail > Uninstall Device admin app
- ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN = 873;
-
- // ACTION: Settings > App detail > Disable app
- ACTION_SETTINGS_DISABLE_APP = 874;
-
- // ACTION: Settings > App detail > Enable app
- ACTION_SETTINGS_ENABLE_APP = 875;
-
- // ACTION: Settings > App detail > Clear data
- ACTION_SETTINGS_CLEAR_APP_DATA = 876;
-
- // ACTION: Settings > App detail > Clear cache
- ACTION_SETTINGS_CLEAR_APP_CACHE = 877;
-
- // ACTION: Logs pressing the "Clear app" button in the app info settings page for an instant
- // app.
- // VALUE: The package name of the app
- ACTION_SETTINGS_CLEAR_INSTANT_APP = 923;
-
- // OPEN: Assist Gesture training intro in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_INTRO = 991;
-
- // OPEN: Assist Gesture training enrolling in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_ENROLLING = 992;
-
- // OPEN: Assist Gesture training finished in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE_TRAINING_FINISHED = 993;
-
- // ACTION: Update default app from Settings
- ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000;
-
- // ACTION: Settings > Wi-Fi > [Long press network] > Sign in to network
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_WIFI_SIGNIN = 1008;
-
- // ACTION: Settings > Notification Settings > Open application notification
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_OPEN_APP_NOTIFICATION_SETTING = 1016;
-
- // ACTION: Settings > App Info > Open app settings
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_OPEN_APP_SETTING = 1017;
-
- // ACTION: Collect PSD Signals
- // CATEGORY: SETTINGS
- // OS: O DR
- ACTION_PSD_LOADER = 1019;
-
- // OPEN: Settings > Trampoline Intent > Settings page
- // CATEGORY: SETTINGS
- // OS: O DR
- TRAMPOLINE_SETTINGS_EVENT = 1033;
-
- // ACTION: Logged when user tries to pair a Bluetooth device without name from Settings app
- // CATEGORY: SETTINGS
- // OS: O MR
- ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES = 1096;
-
- // ACTION: Settings > Network & Internet > Mobile network > Network
- // CATEGORY: SETTINGS
- ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK = 1210;
-
- // ACTION: DND Settings > Priority only allows > Alarms toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_ALARMS = 1226;
-
- // ACTION: DND Settings > Priority only allows > Media toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_MEDIA = 1227;
-
- // ACTION: A private dns mode been selected by user
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_PRIVATE_DNS_MODE = 1249;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name > OK
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK = 1267;
-
- // OPEN: Settings > Sound > Do Not Disturb > TURN ON NOW/TURN OFF NOW
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_TOGGLE_DND_BUTTON = 1268;
-
- // ACTION: DND Settings > What to block > full screen intents
- // SUBTYPE: false is allowed, true is blocked
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS = 1332;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_LIGHT = 1333;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_PEEK = 1334;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_STATUS = 1335;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_BADGE = 1336;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_AMBIENT = 1337;
-
- // ACTION: DND Settings > What to block
- // SUBTYPE: false is allowed, true is blocked
- // OS: P
- ACTION_ZEN_BLOCK_NOTIFICATION_LIST = 1338;
-
- // ACTION: DND Settings > Priority only allows > System toggle
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ALLOW_SYSTEM = 1340;
-
- // ACTION: Settings > Battery settings > Battery tip > App restriction tip
- // OS: P
- ACTION_APP_RESTRICTION_TIP = 1347;
-
- // ACTION: Settings > Battery settings > Battery tip > High usage tip
- // OS: P
- ACTION_HIGH_USAGE_TIP = 1348;
-
- // ACTION: Settings > Battery settings > Battery tip > Summary tip
- // OS: P
- ACTION_SUMMARY_TIP = 1349;
-
- // ACTION: Settings > Battery settings > Battery tip > Smart battery tip
- // OS: P
- ACTION_SMART_BATTERY_TIP = 1350;
-
- // ACTION: Settings > Battery settings > Battery tip > Early warning tip
- // OS: P
- ACTION_EARLY_WARNING_TIP = 1351;
-
- // ACTION: Settings > Battery settings > Battery tip > Low battery tip
- // OS: P
- ACTION_LOW_BATTERY_TIP = 1352;
-
- // ACTION: Settings > Battery settings > Battery tip > App restriction list shown
- // OS: P
- ACTION_APP_RESTRICTION_TIP_LIST = 1353;
-
- // ACTION: Settings > Battery settings > Battery tip > High usage list shown
- // OS: P
- ACTION_HIGH_USAGE_TIP_LIST = 1354;
-
- // ACTION: Settings > Battery settings > Battery tip > Open app restriction page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_APP_RESTRICTION_PAGE = 1361;
-
- // ACTION: Settings > Battery settings > Battery tip > Restrict app
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_RESTRICT_APP = 1362;
-
- // ACTION: Settings > Battery settings > Battery tip > Unrestrict app
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_UNRESTRICT_APP = 1363;
-
- // ACTION: Settings > Battery settings > Battery tip > Open smart battery page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_SMART_BATTERY = 1364;
-
- // ACTION: Settings > Battery settings > Battery tip > Turn on battery saver
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_TURN_ON_BATTERY_SAVER = 1365;
-
- // ACTION: Settings > Anomaly receiver > Anomaly received
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ANOMALY_TRIGGERED = 1367;
-
- // ACTION: A Settings Slice is requested
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_SETTINGS_SLICE_REQUESTED = 1371;
-
- // ACTION: A Settings Slice is updated with new value
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_SETTINGS_SLICE_CHANGED = 1372;
-
- // OPEN: DND onboarding activity > Ok button
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_OK = 1378;
-
- // OPEN: DND onboarding activity > Settings link
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_SETTINGS = 1379;
-
- // ACTION: Settings > Anomaly receiver > Anomaly ignored, don't show up in battery settings
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ANOMALY_IGNORED = 1387;
-
- // ACTION: Settings > Battery settings > Battery tip > Open battery saver page
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_TIP_OPEN_BATTERY_SAVER_PAGE = 1388;
-
- // ACTION: DND Settings > What to block
- // OS: P
- ACTION_ZEN_SOUND_ONLY = 1396;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_SOUND_AND_VIS_EFFECTS = 1397;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_SHOW_CUSTOM = 1398;
-
- // ACTION: DND Settings > Notifications
- // OS: P
- ACTION_ZEN_CUSTOM = 1399;
-
- // OPEN: DND onboarding activity > don't update button
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS = 1406;
-
- // ACTION: Storage initialization wizard initialization choice of external/portable
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_INIT_EXTERNAL = 1407;
-
- // ACTION: Storage initialization wizard initialization choice of internal/adoptable
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_INIT_INTERNAL = 1408;
-
- // ACTION: Storage initialization wizard benchmark fast choice of continue
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_FAST_CONTINUE = 1409;
-
- // ACTION: Storage initialization wizard benchmark slow choice of continue
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_SLOW_CONTINUE = 1410;
-
- // ACTION: Storage initialization wizard benchmark slow choice of abort
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_BENCHMARK_SLOW_ABORT = 1411;
-
- // ACTION: Storage initialization wizard migration choice of now
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_MIGRATE_NOW = 1412;
-
- // ACTION: Storage initialization wizard migration choice of later
- // CATEGORY: SETTINGS
- // OS: P
- ACTION_STORAGE_MIGRATE_LATER = 1413;
-
- // OPEN: Settings > Sound > Switch a2dp devices dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SWITCH_A2DP_DEVICES = 1415;
-
-
- // OPEN: Settings > Sound > Switch hfp devices dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SWITCH_HFP_DEVICES = 1416;
-
- // OPEN: QS Sensor Privacy Mode tile shown
- // ACTION: QS Sensor Privacy Mode tile tapped
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: QUICK_SETTINGS
- // OS: Q
- QS_SENSOR_PRIVACY = 1598;
-
- // ACTION: Tap & Pay -> Default Application Setting -> Use Forground
- ACTION_NFC_PAYMENT_FOREGROUND_SETTING = 1622;
-
- // ACTION: Tap & Pay -> Default Application Setting -> Use Default
- ACTION_NFC_PAYMENT_ALWAYS_SETTING = 1623;
-
- // ACTION: Settings > Search Bar > Avatar
- // CATEGORY: SETTINGS
- // OS: Q
- CLICK_ACCOUNT_AVATAR = 1643;
-
- // ACTION: Set new password (action intent android.app.action.SET_NEW_PASSWORD)
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_SET_NEW_PASSWORD = 1645;
-
- // ACTION: Set new password (action intent android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD)
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = 1646;
-
- // ACTION: An interaction with a Slice or other component in the Panel.
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_PANEL_INTERACTION = 1658;
-
- // ACTION: Show Contextual homepage. Log total loading latency.
- ACTION_CONTEXTUAL_HOME_SHOW = 1662;
-
- // ACTION: Contextual card displays
- ACTION_CONTEXTUAL_CARD_SHOW = 1663;
-
- // ACTION: Contextual cards are eligible to be shown, but don't rank high
- ACTION_CONTEXTUAL_CARD_NOT_SHOW = 1664;
-
- // ACTION: Settings > long press a card, and click dismiss
- // Contextual card is dismissed
- ACTION_CONTEXTUAL_CARD_DISMISS = 1665;
-
- // ACTION: Settings > click a card
- // Contextual card is clicked
- ACTION_CONTEXTUAL_CARD_CLICK = 1666;
-
- // Mapping: go/at-mapping
- ACTION_ATSG = 1674;
-
- ACTION_ATPG = 1675;
-
- ACTION_ATCLPB = 1676;
-
- ACTION_ATCGIB = 1677;
-
- ACTION_ATCPAB = 1678;
-
- ACTION_ATCSAUC = 1679;
-
- ACTION_ATCSCUC = 1680;
-
- ACTION_ATCHNUC = 1681;
-
- // ACTION: Individual contextual card loading time
- ACTION_CONTEXTUAL_CARD_LOAD = 1684;
-
- //ACTION: Contextual card loading timeout
- ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
-
- //ACTION: Log result for each card's eligibility check
- ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
-
- // ACTION: Display white balance setting enabled or disabled.
- // CATEGORY: SETTINGS
- // OS: Q
- ACTION_DISPLAY_WHITE_BALANCE_SETTING_CHANGED = 1703;
-
- // ACTION: Share a Wi-Fi network by generating a QR code
- ACTION_SETTINGS_SHARE_WIFI_QR_CODE = 1710;
-
- // ACTION: Connect to a Wi-Fi network by scanning a QR code
- ACTION_SETTINGS_ENROLL_WIFI_QR_CODE = 1711;
-
- // ACTION: Share Wi-Fi hotspot by generating a QR code
- ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE = 1712;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Invalid data
- ACTION_VERIFY_SLICE_ERROR_INVALID_DATA = 1725;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Parsing error
- ACTION_VERIFY_SLICE_PARSING_ERROR = 1726;
-
- // ACTION: Settings > Initialize Search bar > Verify Slice > Other exception
- ACTION_VERIFY_SLICE_OTHER_EXCEPTION = 1727;
-
- // Custom tag to evaluate the consuming time of the Controller.updateState.
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONTROLLER_UPDATE_STATE = 1728;
-
- // Custom tag to evaluate the consuming time from onAttach to
- // DashboardFragment.updatePreferenceStates.
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_DASHBOARD_VISIBLE_TIME = 1729;
-
- // ACTION: Allow "Access all files" for an app
- APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_ALLOW = 1730;
-
- // ACTION: Deny "Access all files" for an app
- APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_DENY = 1731;
-
- // ACTION: Battery feature usage
- ACTION_BATTERY_OPTION_FEATURE_USAGE = 1732;
-
- // ACTION: Battery feature runtime event
- ACTION_BATTERY_OPTION_RUNTIME_EVENT = 1733;
-
- // ACTION: Settings > Developer Options > Toggle on Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_ADB_WIRELESS_ON = 1734;
-
- // ACTION: Settings > Developer Options > Toggle off Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_ADB_WIRELESS_OFF = 1735;
-
- // ACTION: Change Wi-Fi hotspot name
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_NAME = 1736;
-
- // ACTION: Change Wi-Fi hotspot password
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_PASSWORD = 1737;
-
- // ACTION: Settings > Security > Toggle on Confirm Sim deletion
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONFIRM_SIM_DELETION_ON = 1738;
-
- // ACTION: Settings > Security > Toggle off Confirm Sim deletion
- // CATEGORY: SETTINGS
- // OS: R
- ACTION_CONFIRM_SIM_DELETION_OFF = 1739;
-
- // ACTION: Settings > System > Gestures > Double tap > Toggle on Double tap
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_ENABLED = 1740;
-
- // ACTION: Settings > System > Gestures > Double tap > Toggle off Double tap
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_DISABLED = 1741;
-
- // ACTION: Settings > System > Gestures > Double tap > Invoke Assistant
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_ACTION_ASSISTANT = 1742;
-
- // ACTION: Settings > System > Gestures > Double tap > Take screenshot
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_ACTION_SCREENSHOT = 1743;
-
- // ACTION: Settings > System > Gestures > Double tap > Play and pause
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_ACTION_PLAY_PAUSE = 1744;
-
- // ACTION: Settings > System > Gestures > Double tap > Open app overview
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_ACTION_OVERVIEW = 1745;
-
- // ACTION: Settings > System > Gestures > Double tap > Open notification shade
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_ACTION_NOTIFICATION_SHADE = 1746;
-
- // ACTION: Settings > System > Gestures > Double tap > Require harder taps
- // CATEGORY: SETTINGS
- // OS: S
- ACTION_COLUMBUS_LOW_SENSITIVITY = 1747;
-
- // OPEN: Columbus Gesture training intro in Settings
- // CATEGORY: SETTINGS
- // OS: S
- SETTINGS_COLUMBUS_GESTURE_TRAINING_INTRO = 1748;
-
- // OPEN: Columbus Gesture training enrolling in Settings
- // CATEGORY: SETTINGS
- // OS: S
- SETTINGS_COLUMBUS_GESTURE_TRAINING_ENROLLING = 1749;
-
- // OPEN: Columbus Gesture training finished in Settings
- // CATEGORY: SETTINGS
- // OS: S
- SETTINGS_COLUMBUS_GESTURE_TRAINING_FINISHED = 1750;
-}
-
-/**
- * Id for Settings pages. Each page must have its own unique Id.
- */
-enum PageId {
- // Unknown page. Should not be used in production code.
- PAGE_UNKNOWN = 0;
-
- // OPEN: Settings > Accessibility
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY = 2;
-
- // OPEN: Settings > Accessibility > Captions preference
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_CAPTION_PROPERTIES = 3;
-
- // OPEN: Settings > Accessibility > [Service]
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_SERVICE = 4;
-
- // OPEN: Settings > Accessibility > Color correction
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
-
- // OPEN: Settings > Accessibility > Accessibility shortcut
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
-
- // OPEN: Settings > Accessibility > Magnification gestures (Renamed in O)
- // OPEN: Settings > Accessibility > Magnification > Magnify with triple-tap
- // OPEN: Settings > Accessibility > Magnification > Magnify with button
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
-
- // OPEN: Settings > Accounts
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNT = 8;
-
- // OPEN: Settings > Accounts > [Single Account Sync Settings]
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNTS_ACCOUNT_SYNC = 9;
-
- // OPEN: Settings > Accounts > Add an account
- // CATEGORY: SETTINGS
- // OS: 6.0
- ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
-
- // OPEN: Settings > Cellular network settings > APNs
- // CATEGORY: SETTINGS
- // OS: 6.0
- APN = 12;
-
- // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APN_EDITOR = 13;
-
- // OPEN: Settings > Apps > Configure apps > App links > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_APP_LAUNCH = 17;
-
- // OPEN: Settings > Internal storage > Apps storage > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_APP_STORAGE = 19;
-
- // OPEN: Settings > Apps > [App info]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_INSTALLED_APP_DETAILS = 20;
-
- // OPEN: Settings > Memory > App usage > [App Memory usage]
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_PROCESS_STATS_DETAIL = 21;
-
- // OPEN: Settings > Memory > App usage
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_PROCESS_STATS_UI = 23;
-
- // OPEN: Choose Bluetooth device (ex: when sharing)
- // CATEGORY: SETTINGS
- // OS: 6.0
- BLUETOOTH_DEVICE_PICKER = 25;
-
- // OPEN: Settings > Security > Choose screen lock
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_GENERIC = 27;
-
- // OPEN: Settings > Security > Choose screen lock > Choose your password
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_PASSWORD = 28;
-
- // OPEN: Settings > Security > Choose screen lock > Choose your pattern
- // CATEGORY: SETTINGS
- // OS: 6.0
- CHOOSE_LOCK_PATTERN = 29;
-
- // OPEN: Settings > Security > Choose screen lock > Confirm your password
- // CATEGORY: SETTINGS
- // OS: 6.0
- CONFIRM_LOCK_PASSWORD = 30;
-
- // OPEN: Settings > Security > Choose screen lock > Confirm your pattern
- // CATEGORY: SETTINGS
- // OS: 6.0
- CONFIRM_LOCK_PATTERN = 31;
-
- // OPEN: Settings > Security > Encrypt phone
- // CATEGORY: SETTINGS
- // OS: 6.0
- CRYPT_KEEPER = 32;
-
- // OPEN: Settings > Security > Encrypt phone > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- CRYPT_KEEPER_CONFIRM = 33;
-
- // OPEN: Settings (Root page)
- // CATEGORY: SETTINGS
- // OS: 6.0
- DASHBOARD_SUMMARY = 35;
-
- // OPEN: Settings > Data usage
- // CATEGORY: SETTINGS
- // OS: 6.0
- DATA_USAGE_SUMMARY = 37;
-
- // OPEN: Settings > Date & time
- // CATEGORY: SETTINGS
- // OS: 6.0
- DATE_TIME = 38;
-
- // OPEN: Settings > Developer options
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVELOPMENT = 39;
-
- // OPEN: Settings > About phone
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVICEINFO = 40;
-
- // OPEN: Settings > Internal storage
- // CATEGORY: SETTINGS
- // OS: 6.0
- DEVICEINFO_STORAGE = 42;
-
- // OPEN: Settings > Display
- // CATEGORY: SETTINGS
- // OS: 6.0
- DISPLAY = 46;
-
- // OPEN: Settings > Display > Daydream
- // CATEGORY: SETTINGS
- // OS: 6.0
- DREAM = 47;
-
- // OPEN: Settings > Security > Screen lock > Secure start-up
- // CATEGORY: SETTINGS
- // OS: 6.0
- ENCRYPTION = 48;
-
- // OPEN: Settings > Security > Nexus Imprint
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT = 49;
-
- // OPEN: Settings > Battery > History details
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
-
- // OPEN: Settings > Battery > Battery saver
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_BATTERY_SAVER = 52;
-
- // OPEN: Settings > Battery > [App Use details]
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_POWER_USAGE_DETAIL = 53;
-
- // OPEN: Settings > Security > SIM card lock settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- ICC_LOCK = 56;
-
- // OPEN: Settings > Language & input > Physical keyboard
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_KEYBOARD = 58;
-
- // OPEN: Settings > Language & input > Spell checker
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_SPELL_CHECKERS = 59;
-
- // OBSOLETE
- INPUTMETHOD_SUBTYPE_ENABLER = 60;
-
- // OPEN: Settings > Language & input > Personal dictionary
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_USER_DICTIONARY = 61;
-
- // OPEN: Settings > Language & input > Add word
- // CATEGORY: SETTINGS
- // OS: 6.0
- INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
-
- // OPEN: Settings > Location
- // CATEGORY: SETTINGS
- // OS: 6.0
- LOCATION = 63;
-
- // OPEN: Settings > Apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_APPLICATIONS = 65;
-
- // OPEN: Settings > Backup & reset > Factory data reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- MASTER_CLEAR = 66;
-
- // OPEN: Settings > Backup & reset > Factory data reset > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- MASTER_CLEAR_CONFIRM = 67;
-
- // OPEN: Settings > More > Android Beam
- // CATEGORY: SETTINGS
- // OS: 6.0
- NFC_BEAM = 69;
-
- // OPEN: Settings > Tap & pay
- // CATEGORY: SETTINGS
- // OS: 6.0
- NFC_PAYMENT = 70;
-
- // OPEN: Settings > Sound & notification > App notifications > [App]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_APP_NOTIFICATION = 72;
-
- // OBSOLETE
- NOTIFICATION_REDACTION = 74;
-
- // OPEN: Settings Widget > Notification log
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_STATION = 75;
-
- // OPEN: Settings > Sound & notification > Do not disturb
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE = 76;
-
-
- // OPEN: Print job notification > Print job settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_JOB_SETTINGS = 78;
-
- // OPEN: Settings > Printing > [Print Service]
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_SERVICE_SETTINGS = 79;
-
- // OPEN: Settings > Printing
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRINT_SETTINGS = 80;
-
- // OPEN: Settings > Backup & reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- PRIVACY = 81;
-
- //OBSOLETE
- PROXY_SELECTOR = 82;
-
- // OPEN: Settings > Backup & reset > Network settings reset
- // CATEGORY: SETTINGS
- // OS: 6.0
- RESET_NETWORK = 83;
-
- // OPEN: Settings > Backup & reset > Network settings reset > Confirm
- // CATEGORY: SETTINGS
- // OS: 6.0
- RESET_NETWORK_CONFIRM = 84;
-
- // OPEN: Settings > Developer Options > Running Services
- // CATEGORY: SETTINGS
- // OS: 6.0
- RUNNING_SERVICE_DETAILS = 85;
-
- // OPEN: Settings > Security > Screen pinning
- // CATEGORY: SETTINGS
- // OS: 6.0
- SCREEN_PINNING = 86;
-
- // OPEN: Settings > Security
- // CATEGORY: SETTINGS
- // OS: 6.0
- SECURITY = 87;
-
- // OPEN: Settings > SIM cards
- // CATEGORY: SETTINGS
- // OS: 6.0
- SIM = 88;
-
- // OBSOLETE
- TESTING = 89;
-
- // OPEN: Settings > More > Tethering & portable hotspot
- // CATEGORY: SETTINGS
- // OS: 6.0
- TETHER = 90;
-
- // OPEN: Settings > Security > Trust agents
- // CATEGORY: SETTINGS
- // OS: 6.0
- TRUST_AGENT = 91;
-
- // OPEN: Settings > Security > Trusted credentials
- // CATEGORY: SETTINGS
- // OS: 6.0
- TRUSTED_CREDENTIALS = 92;
-
- // OPEN: Settings > Language & input > TTS output > [Engine] > Settings
- // CATEGORY: SETTINGS
- // OS: 6.0
- TTS_ENGINE_SETTINGS = 93;
-
- // OPEN: Settings > Language & input > Text-to-speech output
- // CATEGORY: SETTINGS
- // OS: 6.0
- TTS_TEXT_TO_SPEECH = 94;
-
- // OPEN: Settings > Security > Apps with usage access
- // CATEGORY: SETTINGS
- // OS: 6.0
- USAGE_ACCESS = 95;
-
- // OPEN: Settings > Users
- // CATEGORY: SETTINGS
- // OS: 6.0
- USER = 96;
-
- // OPEN: Settings > Users > [Restricted profile app & content access]
- // CATEGORY: SETTINGS
- // OS: 6.0
- USERS_APP_RESTRICTIONS = 97;
-
- // OPEN: Settings > Users > [User settings]
- // CATEGORY: SETTINGS
- // OS: 6.0
- USER_DETAILS = 98;
-
- // OPEN: Settings > More > VPN
- // CATEGORY: SETTINGS
- // OS: 6.0
- VPN = 100;
-
- // OPEN: Settings > Display > Choose wallpaper from
- // CATEGORY: SETTINGS
- // OS: 6.0
- WALLPAPER_TYPE = 101;
-
- // OPEN: Settings > Display > Cast
- // CATEGORY: SETTINGS
- // OS: 6.0
- WFD_WIFI_DISPLAY = 102;
-
- // OPEN: Settings > Wi-Fi
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI = 103;
-
- // OPEN: Settings > More > Wi-Fi Calling
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_CALLING = 105;
-
- // OPEN: Settings > Wi-Fi > Saved networks
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_SAVED_ACCESS_POINTS = 106;
-
- // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct
- // CATEGORY: SETTINGS
- // OS: 6.0
- WIFI_P2P = 109;
-
- // OPEN: Settings > Apps > Configure apps > App permissions
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_ADVANCED = 130;
-
- // OPEN: Settings > Location > Scanning
- // CATEGORY: SETTINGS
- // OS: 6.0
- LOCATION_SCANNING = 131;
-
- // OPEN: Settings > Sound & notification > App notifications
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
-
- // OPEN: Settings > Sound & notification > DND > Priority only allows
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_PRIORITY = 141;
-
- // OPEN: Settings > Sound & notification > DND > Automatic rules
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
-
- // OPEN: Settings > Sound & notification > DND > [Time based rule]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
-
- // OPEN: Settings > Apps > Configure apps > App links
- // CATEGORY: SETTINGS
- // OS: 6.0
- MANAGE_DOMAIN_URLS = 143;
-
- // OPEN: Settings > Sound & notification > DND > [Event rule]
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
-
- // OPEN: Settings > Sound & notification > Notification access
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ACCESS = 179;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb access
- // CATEGORY: SETTINGS
- // OS: 6.0
- NOTIFICATION_ZEN_MODE_ACCESS = 180;
-
- // OPEN: Settings > Internal storage > Apps storage
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_STORAGE_APPS = 182;
-
- // OPEN: Settings > Security > Usage access
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
-
- // OPEN: Settings > Battery > Battery optimization
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_HIGH_POWER_APPS = 184;
-
- // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input
- // CATEGORY: SETTINGS
- // OS: 6.0
- APPLICATIONS_MANAGE_ASSIST = 201;
-
- // OPEN: Settings > Memory
- // CATEGORY: SETTINGS
- // OS: 6.0
- PROCESS_STATS_SUMMARY = 202;
-
- // OPEN: Settings > Apps > Configure Apps > Display over other apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- SYSTEM_ALERT_WINDOW_APPS = 221;
-
- // OPEN: Settings > About phone > Legal information
- // CATEGORY: SETTINGS
- // OS: 6.0
- ABOUT_LEGAL_SETTINGS = 225;
-
-
- // OPEN: Settings > Developer options > Inactive apps
- // CATEGORY: SETTINGS
- // OS: 6.0
- FUELGAUGE_INACTIVE_APPS = 238;
-
- // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLLING = 240;
- // OPEN: Fingerprint Enroll > Find Sensor
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_FIND_SENSOR = 241;
-
- // OPEN: Fingerprint Enroll > Fingerprint Enrolled!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_FINISH = 242;
-
- // OPEN: Fingerprint Enroll introduction
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_INTRO = 243;
-
- // OPEN: Fingerprint Enroll > Let's Start!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_SIDECAR = 245;
-
- // OPEN: Fingerprint Enroll SUW > Let's Start!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLLING_SETUP = 246;
-
- // OPEN: Fingerprint Enroll SUW > Find Sensor
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_FIND_SENSOR_SETUP = 247;
-
- // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled!
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_FINISH_SETUP = 248;
-
- // OPEN: Fingerprint Enroll SUW introduction
- // CATEGORY: SETTINGS
- // OS: 6.0
- FINGERPRINT_ENROLL_INTRO_SETUP = 249;
-
- // OPEN: Settings > Developer Options > Background Check
- // CATEGORY: SETTINGS
- // OS: N
- BACKGROUND_CHECK_SUMMARY = 258;
-
- // OPEN: Settings > Notifications > [App] > Channel Notifications
- // CATEGORY: SETTINGS
- // OS: N
- NOTIFICATION_TOPIC_NOTIFICATION = 265;
-
- // OPEN: Settings > Security > User credentials
- // CATEGORY: Settings
- // OS: N
- USER_CREDENTIALS = 285;
-
- // Logs that the user has edited the enabled VR listeners.
- // CATEGORY: SETTINGS
- // OS: N
- VR_MANAGE_LISTENERS = 334;
-
- // Settings -> Accessibility -> Click after pointer stops moving
- // CATEGORY: SETTINGS
- // OS: N
- ACCESSIBILITY_TOGGLE_AUTOCLICK = 335;
-
- // Settings -> Sound
- // CATEGORY: SETTINGS
- // OS: N
- SOUND = 336;
-
- // Settings -> Notifications -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- CONFIGURE_NOTIFICATION = 337;
-
- // Settings -> Wi-Fi -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- CONFIGURE_WIFI = 338;
-
- // Settings -> Display -> Display size
- // OS: N
- DISPLAY_SCREEN_ZOOM = 339;
-
- // Settings -> Display -> Font size
- // CATEGORY: SETTINGS
- // OS: N
- ACCESSIBILITY_FONT_SIZE = 340;
-
- // Settings -> Data usage -> Cellular/Wi-Fi data usage
- // CATEGORY: SETTINGS
- // OS: N
- DATA_USAGE_LIST = 341;
-
- // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear
- // CATEGORY: SETTINGS
- // OS: N
- BILLING_CYCLE = 342;
-
- // DATA_USAGE_LIST -> Any item or App info -> Data usage
- // CATEGORY: SETTINGS
- // OS: N
- APP_DATA_USAGE = 343;
-
- // Settings -> Language & input -> Language
- // CATEGORY: SETTINGS
- // OS: N
- USER_LOCALE_LIST = 344;
-
- // Settings -> Language & input -> Virtual keyboard
- // CATEGORY: SETTINGS
- // OS: N
- VIRTUAL_KEYBOARDS = 345;
-
- // Settings -> Language & input -> Physical keyboard
- // CATEGORY: SETTINGS
- // OS: N
- PHYSICAL_KEYBOARDS = 346;
-
- // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard
- // CATEGORY: SETTINGS
- // OS: N
- ENABLE_VIRTUAL_KEYBOARDS = 347;
-
- // Settings -> Data usage -> Data Saver
- // CATEGORY: SETTINGS
- // OS: N
- DATA_SAVER_SUMMARY = 348;
-
- // Settings -> Data usage -> Data Saver -> Unrestricted data access
- // CATEGORY: SETTINGS
- // OS: N
- DATA_USAGE_UNRESTRICTED_ACCESS = 349;
-
- // Settings -> Apps -> Gear -> Special access
- SPECIAL_ACCESS = 351;
-
- // OPEN: SUW Welcome Screen -> Vision Settings
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY = 367;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification gestures (Renamed in O)
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with triple-tap
- // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with button
- // ACTION: New magnification gesture configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 368;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Font size
- // ACTION: New font size is chosen
- // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is largest
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_FONT_SIZE = 369;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Display size
- // ACTION: New display size is chosen
- // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is larger, 4 is largest
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_DISPLAY_SIZE = 370;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> TalkBack
- // ACTION: New screen reader configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SCREEN_READER = 371;
-
- // Airplane mode on
- SETTINGS_CONDITION_AIRPLANE_MODE = 377;
- // AKA Data saver on
- SETTINGS_CONDITION_BACKGROUND_DATA = 378;
- // Battery saver on
- SETTINGS_CONDITION_BATTERY_SAVER = 379;
- // Cellular data off
- SETTINGS_CONDITION_CELLULAR_DATA = 380;
- // Do not disturb on
- SETTINGS_CONDITION_DND = 381;
- // Hotspot on
- SETTINGS_CONDITION_HOTSPOT = 382;
- // Work profile off
- SETTINGS_CONDITION_WORK_MODE = 383;
-
- // Settings > Apps > Gear > Special Access > Premium SMS access
- PREMIUM_SMS_ACCESS = 388;
-
- // OPEN: Settings > Accounts > Work profile settings
- // CATEGORY: SETTINGS
- ACCOUNTS_WORK_PROFILE_SETTINGS = 401;
-
- // Settings -> Dev options -> Convert to file encryption
- CONVERT_FBE = 402;
-
- // Settings -> Dev options -> Convert to file encryption -> WIPE AND CONVERT...
- CONVERT_FBE_CONFIRM = 403;
-
- // Settings -> Dev options -> Running services
- RUNNING_SERVICES = 404;
-
- // The dialog shown by 3P intent to change current webview implementation.
- WEBVIEW_IMPLEMENTATION = 405;
-
- // OPEN: Settings > Internal storage > Storage manager
- // CATEGORY: SETTINGS
- STORAGE_MANAGER_SETTINGS = 458;
-
- // OPEN: Settings -> Gestures
- // CATEGORY: SETTINGS
- SETTINGS_GESTURES = 459;
-
- // OPEN: Settings > Display > Night Light
- // CATEGORY: SETTINGS
- NIGHT_DISPLAY_SETTINGS = 488;
-
- // Night Light on
- SETTINGS_CONDITION_NIGHT_DISPLAY = 492;
-
- // OPEN: Settings > Language & input > Personal dictionary (single locale)
- USER_DICTIONARY_SETTINGS = 514;
-
- // OPEN: Settings > Date & time > Select time zone
- ZONE_PICKER = 515;
-
- // OPEN: Settings > Security > Device administrators
- DEVICE_ADMIN_SETTINGS = 516;
-
- // OPEN: Settings > Security > Factory Reset Protection dialog
- DIALOG_FRP = 528;
-
- // OPEN: Settings > Custom list preference with confirmation message
- DIALOG_CUSTOM_LIST_CONFIRMATION = 529;
-
- // OPEN: Settings > APN Editor > Error dialog
- DIALOG_APN_EDITOR_ERROR = 530;
-
- // OPEN: Settings > Users > Edit owner info dialog
- DIALOG_OWNER_INFO_SETTINGS = 531;
-
- // OPEN: Settings > Security > Use one lock dialog
- DIALOG_UNIFICATION_CONFIRMATION = 532;
-
- // OPEN: Settings > Security > User Credential
- DIALOG_USER_CREDENTIAL = 533;
-
- // OPEN: Settings > Accounts > Remove account
- DIALOG_REMOVE_USER = 534;
-
- // OPEN: Settings > Accounts > Confirm auto sync dialog
- DIALOG_CONFIRM_AUTO_SYNC_CHANGE = 535;
-
- // OPEN: Settings > Apps > Dialog for running service details
- DIALOG_RUNNIGN_SERVICE = 536;
-
- // OPEN: Settings > Bluetooth > Rename this device
- DIALOG_BLUETOOTH_RENAME = 538;
-
- // OPEN: Settings > Battery optimization > details for app
- DIALOG_HIGH_POWER_DETAILS = 540;
-
- // OPEN: Settings > Keyboard > Show keyboard layout dialog
- DIALOG_KEYBOARD_LAYOUT = 541;
-
- // OPEN: Settings > WIFI Scan permission dialog
- DIALOG_WIFI_SCAN_MODE = 543;
-
- // OPEN: Settings > Wireless > VPN > Config dialog
- DIALOG_LEGACY_VPN_CONFIG = 545;
-
- // OPEN: Settings > Wireless > VPN > Config dialog for app
- DIALOG_VPN_APP_CONFIG = 546;
-
- // OPEN: Settings > Wireless > VPN > Cannot connect dialog
- DIALOG_VPN_CANNOT_CONNECT = 547;
-
- // OPEN: Settings > Wireless > VPN > Replace existing VPN dialog
- DIALOG_VPN_REPLACE_EXISTING = 548;
-
- // OPEN: Settings > Billing cycle > Edit billing cycle dates dialog
- DIALOG_BILLING_CYCLE = 549;
-
- // OPEN: Settings > Billing cycle > Edit data limit/warning dialog
- DIALOG_BILLING_BYTE_LIMIT = 550;
-
- // OPEN: Settings > Billing cycle > turn on data limit dialog
- DIALOG_BILLING_CONFIRM_LIMIT = 551;
-
- // OPEN: Settings > Service > Turn off notification access dialog
- DIALOG_DISABLE_NOTIFICATION_ACCESS = 552;
-
- // OPEN: Settings > Sound > Use personal sound for work profile dialog
- DIALOG_UNIFY_SOUND_SETTINGS = 553;
-
- // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being granted.
- DIALOG_ZEN_ACCESS_GRANT = 554;
-
- // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being revoked.
- DIALOG_ZEN_ACCESS_REVOKE = 555;
-
- // OPEN: Settings > Zen mode > Dialog that picks time for zen mode.
- DIALOG_ZEN_TIMEPICKER = 556;
-
- // OPEN: Settings > Apps > Dialog that informs user to allow service access for app.
- DIALOG_SERVICE_ACCESS_WARNING = 557;
-
- // OPEN: Settings > Apps > Dialog for app actions (such as force stop/clear data)
- DIALOG_APP_INFO_ACTION = 558;
-
- // OPEN: Settings > Storage > Dialog for forgetting a storage device
- DIALOG_VOLUME_FORGET = 559;
-
- // OPEN: Settings > Storage > Dialog for initializing a volume
- DIALOG_VOLUME_INIT = 561;
-
- // OPEN: Settings > Storage > Dialog for unmounting a volume
- DIALOG_VOLUME_UNMOUNT = 562;
-
- // OPEN: Settings > Storage > Dialog for renaming a volume
- DIALOG_VOLUME_RENAME = 563;
-
- // OPEN: Settings > Storage > Dialog for clear cache
- DIALOG_STORAGE_CLEAR_CACHE = 564;
-
- // OPEN: Settings > Storage > Dialog for system info
- DIALOG_STORAGE_SYSTEM_INFO = 565;
-
- // OPEN: Settings > Storage > Dialog for other info
- DIALOG_STORAGE_OTHER_INFO = 566;
-
- // OPEN: Settings > Storage > Dialog for user info
- DIALOG_STORAGE_USER_INFO = 567;
- // OPEN: Settings > Add fingerprint > Dialog when user touches fingerprint icon.
- DIALOG_FINGERPRINT_ICON_TOUCH = 568;
-
- // OPEN: Settings > Add fingerprint > Error dialog
- DIALOG_FINGERPINT_ERROR = 569;
-
- // OPEN: Settings > Fingerprint > Rename or delete dialog
- DIALOG_FINGERPINT_EDIT = 570;
-
- // OPEN: Settings > Fingerprint > Dialog for deleting last fingerprint
- DIALOG_FINGERPINT_DELETE_LAST = 571;
-
- // OPEN: SUW > Fingerprint > Dialog to confirm skip fingerprint setup entirely.
- DIALOG_FINGERPRINT_SKIP_SETUP = 573;
-
- // OPEN: Settings > Proxy Selector error dialog
- DIALOG_PROXY_SELECTOR_ERROR = 574;
-
- // OPEN: Settings > Wifi > P2P Settings > Disconnect dialog
- DIALOG_WIFI_P2P_DISCONNECT = 575;
-
- // OPEN: Settings > Wifi > P2P Settings > Cancel connection dialog
- DIALOG_WIFI_P2P_CANCEL_CONNECT = 576;
-
- // OPEN: Settings > Wifi > P2P Settings > Rename dialog
- DIALOG_WIFI_P2P_RENAME = 577;
-
- // OPEN: Settings > Wifi > P2P Settings > Forget group dialog
- DIALOG_WIFI_P2P_DELETE_GROUP = 578;
-
- // OPEN: Settings > APN > Restore default dialog
- DIALOG_APN_RESTORE_DEFAULT = 579;
-
- // OPEN: Settings > Encryption interstitial accessibility warning dialog
- DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY = 581;
-
- // OPEN: Settings > Acessibility > Enable accessiblity service dialog
- DIALOG_ACCESSIBILITY_SERVICE_ENABLE = 583;
-
- // OPEN: Settings > Acessibility > Disable accessiblity service dialog
- DIALOG_ACCESSIBILITY_SERVICE_DISABLE = 584;
-
- // OPEN: Settings > Account > Remove account dialog
- DIALOG_ACCOUNT_SYNC_REMOVE = 585;
-
- // OPEN: Settings > Account > Remove account failed dialog
- DIALOG_ACCOUNT_SYNC_FAILED_REMOVAL = 586;
-
- // OPEN: Settings > Account > Cannot do onetime sync dialog
- DIALOG_ACCOUNT_SYNC_CANNOT_ONETIME_SYNC = 587;
-
- // OPEN: Settings > Display > Night light > Set start time dialog
- DIALOG_NIGHT_DISPLAY_SET_START_TIME = 588;
-
- // OPEN: Settings > Display > Night light > Set end time dialog
- DIALOG_NIGHT_DISPLAY_SET_END_TIME = 589;
-
-
-
- // OPEN: Settings > User > Edit info dialog
- DIALOG_USER_EDIT = 590;
-
- // OPEN: Settings > User > Confirm remove dialog
- DIALOG_USER_REMOVE = 591;
-
- // OPEN: Settings > User > Enable calling dialog
- DIALOG_USER_ENABLE_CALLING = 592;
-
- // OPEN: Settings > User > Enable calling and sms dialog
- DIALOG_USER_ENABLE_CALLING_AND_SMS = 593;
-
- // OPEN: Settings > User > Cannot manage device message dialog
- DIALOG_USER_CANNOT_MANAGE = 594;
-
- // OPEN: Settings > User > Add user dialog
- DIALOG_USER_ADD = 595;
-
- // OPEN: Settings > User > Setup user dialog
- DIALOG_USER_SETUP = 596;
-
- // OPEN: Settings > User > Setup profile dialog
- DIALOG_USER_SETUP_PROFILE = 597;
-
- // OPEN: Settings > User > Choose user type dialog
- DIALOG_USER_CHOOSE_TYPE = 598;
-
- // OPEN: Settings > User > Need lockscreen dialog
- DIALOG_USER_NEED_LOCKSCREEN = 599;
-
- // OPEN: Settings > User > Confirm exit guest mode dialog
- DIALOG_USER_CONFIRM_EXIT_GUEST = 600;
-
- // OPEN: Settings > User > Edit user profile dialog
- DIALOG_USER_EDIT_PROFILE = 601;
-
-
- // OPEN: Settings > Wifi > Saved AP > Edit dialog
- DIALOG_WIFI_SAVED_AP_EDIT = 602;
-
- // OPEN: Settings > Wifi > Edit AP dialog
- DIALOG_WIFI_AP_EDIT = 603;
-
- // OPEN: Settings > Wifi > Write config to NFC dialog
- DIALOG_WIFI_WRITE_NFC = 606;
-
- // OPEN: Settings > Date > Date picker dialog
- DIALOG_DATE_PICKER = 607;
-
- // OPEN: Settings > Date > Time picker dialog
- DIALOG_TIME_PICKER = 608;
-
- // OPEN: Settings > Wireless > Manage wireless plan dialog
- DIALOG_MANAGE_MOBILE_PLAN = 609;
-
- // OPEN Settings > Bluetooth > Attempt to connect to device that shows dialog
- BLUETOOTH_DIALOG_FRAGMENT = 613;
-
- // OPEN: Settings > Security
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_SETTINGS = 628;
-
- // OPEN: Settings > System
- SETTINGS_SYSTEM_CATEGORY = 744;
-
- // OPEN: Settings > Storage
- SETTINGS_STORAGE_CATEGORY = 745;
-
- // OPEN: Settings > Network & Internet
- SETTINGS_NETWORK_CATEGORY = 746;
-
- // OPEN: Settings > Connected Device
- SETTINGS_CONNECTED_DEVICE_CATEGORY = 747;
-
- // OPEN: Settings > App & Notification
- SETTINGS_APP_NOTIF_CATEGORY = 748;
-
- // OPEN: Settings > System > Language & Region
- SETTINGS_LANGUAGE_CATEGORY = 750;
-
- // OPEN: Settings > System > Input & Gesture > Swipe fingerprint for notifications
- SETTINGS_GESTURE_SWIPE_TO_NOTIFICATION = 751;
-
- // OPEN: Settings > System > Input & Gesture > Double tap power button gesture
- SETTINGS_GESTURE_DOUBLE_TAP_POWER = 752;
-
- // OPEN: Settings > System > Input & Gesture > Pick up gesture
- SETTINGS_GESTURE_PICKUP = 753;
-
- // OPEN: Settings > System > Input & Gesture > Double tap screen gesture
- SETTINGS_GESTURE_DOUBLE_TAP_SCREEN = 754;
-
- // OPEN: Settings > System > Input & Gesture > Double twist gesture
- SETTINGS_GESTURE_DOUBLE_TWIST = 755;
-
- // OPEN: Settings > Apps > Default Apps > Default browser
- DEFAULT_BROWSER_PICKER = 785;
- // OPEN: Settings > Apps > Default Apps > Default emergency app
- DEFAULT_EMERGENCY_APP_PICKER = 786;
-
- // OPEN: Settings > Apps > Default Apps > Default home
- DEFAULT_HOME_PICKER = 787;
-
- // OPEN: Settings > Apps > Default Apps > Default phone
- DEFAULT_PHONE_PICKER = 788;
-
- // OPEN: Settings > Apps > Default Apps > Default sms
- DEFAULT_SMS_PICKER = 789;
-
- // OPEN: Settings > Apps > Notification > Notification Assistant
- DEFAULT_NOTIFICATION_ASSISTANT = 790;
-
-
- // OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection
- DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791;
-
- // OPEN: Settings > Apps > Default Apps > Default autofill app
- DEFAULT_AUTOFILL_PICKER = 792;
-
- // OPEN: Settings > Apps > Gear > Special Access > Install other apps
- // CATEGORY: SETTINGS
- // OS: 8.0
- MANAGE_EXTERNAL_SOURCES = 808;
-
- // Logs that the user has edited the picture-in-picture settings.
- // CATEGORY: SETTINGS
- SETTINGS_MANAGE_PICTURE_IN_PICTURE = 812;
-
- // OPEN: SUW Welcome Screen -> Vision Settings -> Select to Speak
- // ACTION: Select to Speak configuration is chosen
- // SUBTYPE: 0 is off, 1 is on
- // CATEGORY: SETTINGS
- // OS: N
- SUW_ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK = 817;
-
- // OPEN: Settings > System > Backup
- // CATEGORY: SETTINGS
- // OS: O
- BACKUP_SETTINGS = 818;
-
- // OPEN: Settings > Storage > Games
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_GAMES = 838;
-
- // OPEN: Settings > Storage > Audio and Music
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_MUSIC = 839;
-
- // ACTION: Settings > Storage > Free Up Space to launch Deletion Helper
- // CATEGORY: SETTINGS
- // OS: O
- STORAGE_FREE_UP_SPACE_NOW = 840;
-
- // ACTION: Settings > Storage > Files to open the File Manager
- // CATEGORY: SETTINGS
- // OS: O
- STORAGE_FILES = 841;
-
- // OPEN: Settings > Apps > Default Apps > Assist > Default assist
- DEFAULT_ASSIST_PICKER = 843;
-
- // OPEN: Settings > Apps > Default Apps > Assist > Default voice input
- DEFAULT_VOICE_INPUT_PICKER = 844;
-
- // OPEN: Settings > Storage > [Profile]
- SETTINGS_STORAGE_PROFILE = 845;
-
- // OPEN: Settings > Security & screen lock -> Encryption & crendentials
- // CATEGORY: SETTINGS
- // OS: O
- ENCRYPTION_AND_CREDENTIAL = 846;
-
- // OPEN: Settings > Wi-Fi > Network Details (click on Access Point)
- // CATEGORY: SETTINGS
- // OS: O
- WIFI_NETWORK_DETAILS = 849;
-
- // OPEN: Settings > Wi-Fi > Wifi Preferences -> Advanced -> Network Scorer
- // CATEGORY: SETTINGS
- // OS: O
- SETTINGS_NETWORK_SCORER = 861;
-
- // OPEN: Settings > About device > Model > Hardware info dialog
- DIALOG_SETTINGS_HARDWARE_INFO = 862;
-
- // OPEN: Settings > Security & screen lock -> Lock screen preferences
- // CATEGORY: SETTINGS
- SETTINGS_LOCK_SCREEN_PREFERENCES = 882;
-
-
- // OPEN: Settings -> Display -> When in VR Mode
- VR_DISPLAY_PREFERENCE = 921;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: O
- ACCESSIBILITY_SCREEN_MAGNIFICATION_SETTINGS = 922;
-
- // OPEN: Settings -> System -> Reset options
- RESET_DASHBOARD = 924;
-
- // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
- // CATEGORY: SETTINGS
- // OS: O
- FINGERPRINT_REMOVE_SIDECAR = 934;
-
- // OPEN: Settings > Storage > Movies & TV
- // CATEGORY: SETTINGS
- // OS: O
- APPLICATIONS_STORAGE_MOVIES = 935;
-
- // OPEN: Settings > Security > Managed Device Info > Apps installed
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_INSTALLED_APPS = 938;
-
- // OPEN: Settings > Security > Managed Device Info > nnn permissions
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_PERMISSIONS = 939;
-
-
- // OPEN: Settings > Security > Managed Device Info > Default apps
- // CATEGORY: SETTINGS
- // OS: O
- ENTERPRISE_PRIVACY_DEFAULT_APPS = 940;
-
- // OPEN: Choose screen lock dialog in Settings
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_CHOOSE_LOCK_DIALOG = 990;
-
- // OPEN: Settings > System > Languages & input > Assist gesture
- // CATEGORY: SETTINGS
- // OS: O DR
- SETTINGS_ASSIST_GESTURE = 996;
-
- // OPEN: Settings > Connected Devices > Bluetooth > (click on details link for a paired device)
- BLUETOOTH_DEVICE_DETAILS = 1009;
-
- // OPEN: Settings > credential pages - prompt for key guard configuration confirmation
- CONFIGURE_KEYGUARD_DIALOG = 1010;
-
- // OPEN: Settings > Network > Tether > Wi-Fi hotspot
- WIFI_TETHER_SETTINGS = 1014;
-
- // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
- // -> Edit name button.
- // CATEGORY: SETTINGS
- // OS: O DR
- DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME = 1015;
-
- // OPEN: Settings > Connected devices > Bluetooth > Pair new device
- // CATEGORY: SETTINGS
- // OS: O DR
- BLUETOOTH_PAIRING = 1018;
-
- // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
- // -> Forget button.
- // CATEGORY: SETTINGS
- // OS: O DR
- DIALOG_BLUETOOTH_PAIRED_DEVICE_FORGET = 1031;
-
- // OPEN: Settings > Storage > Photos & Videos
- // CATEGORY: SETTINGS
- // OS: O MR
- APPLICATIONS_STORAGE_PHOTOS = 1092;
-
- // OPEN: Settings > Display > Colors
- // CATEGORY: SETTINGS
- // OS: O MR
- COLOR_MODE_SETTINGS = 1143;
-
- // OPEN: Settings > Developer Options > Experiment dashboard
- // CATEGORY: SETTINGS
- SETTINGS_FEATURE_FLAGS_DASHBOARD = 1217;
-
- // OPEN: Settings > Notifications > [App] > Topic Notifications
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_CHANNEL_GROUP = 1218;
-
- // OPEN: Settings > Developer options > Enable > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_DEVELOPMENT_OPTIONS = 1219;
-
- // OPEN: Settings > Developer options > OEM unlocking > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_OEM_UNLOCKING = 1220;
-
- // OPEN: Settings > Developer options > USB debugging > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_ENABLE_ADB = 1222;
-
- // OPEN: Settings > Security > Nexus Imprint > [Fingerprint]
- // CATEGORY: SETTINGS
- // OS: P
- FINGERPRINT_AUTHENTICATE_SIDECAR = 1221;
-
- // OPEN: Settings > Developer options > Revoke USB debugging authorizations > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_CLEAR_ADB_KEYS = 1223;
-
- // Open: Settings > Developer options > Quick setting tile config
- // CATEGORY: SETTINGS
- // OS: P
- DEVELOPMENT_QS_TILE_CONFIG = 1224;
-
- // OPEN: Settings > Developer options > Store logger data persistently on device > Info dialog
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_LOG_PERSIST = 1225;
-
- // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling
- // CATEGORY: SETTINGS
- // OS: P
- WIFI_CALLING_FOR_SUB = 1230;
-
- // Open: Settings > Dev options > Oem unlock > lock it > warning dialog.
- // OS: P
- DIALOG_OEM_LOCK_INFO = 1238;
-
- // Open: Settings > System > About phone > IMEI
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_IMEI_INFO = 1240;
-
- // OPEN: Settings > System > About Phone > Sim status
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_SIM_STATUS = 1246;
-
- // OPEN: Settings > System > About Phone > Android Version
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_FIRMWARE_VERSION = 1247;
-
- // OPEN: Settings > Battery(version 2)
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_POWER_USAGE_SUMMARY_V2 = 1263;
-
- // OPEN: Settings > Connected devices > Connection preferences
- // CATEGORY: SETTINGS
- // OS: P
- CONNECTION_DEVICE_ADVANCED = 1264;
-
- // OPEN: Settings > Security > Screen lock gear icon
- // CATEGORY: SETTINGS
- // OS: P
- SCREEN_LOCK_SETTINGS = 1265;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Delete rule (trash can icon)
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_DELETE_RULE_DIALOG = 1266;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule > Event/Time
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG = 1269;
-
- // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG = 1270;
-
- // OPEN: Settings > Battery > Smart Battery
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_SMART_BATTERY = 1281;
-
- // OPEN: Settings > Battery > Smart Battery > Restricted apps
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_RESTRICTED_APP_DETAILS = 1285;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > Turn on now
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_ENABLE_DIALOG = 1286;
-
- // OPEN: Settings->Connected Devices->USB->(click on details link)
- // CATEGORY: SETTINGS
- // OS: P
- USB_DEVICE_DETAILS = 1291;
-
- // OPEN: Settings > Accessibility > Vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION = 1292;
-
- // OPEN: Settings > Accessibility > Vibration > Notification vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION_NOTIFICATION = 1293;
-
- // OPEN: Settings > Accessibility > Vibration > Touch vibration
- // CATEGORY: SETTINGS
- // OS: P
- ACCESSIBILITY_VIBRATION_TOUCH = 1294;
-
- // OPEN: Settings->Developer Options->Default USB
- // CATEGORY: SETTINGS
- // OS: P
- USB_DEFAULT = 1312;
-
- // OPEN: Settings > Battery > Battery tip > Battery tip Dialog
- // CATEGORY: SETTINGS
- // OS: P
- FUELGAUGE_BATTERY_TIP_DIALOG = 1323;
-
- // OPEN: DND Settings > What to block
- // OS: P
- ZEN_WHAT_TO_BLOCK = 1339;
-
- // OPEN: Settings > Sounds > Do Not Disturb > Duration
- // CATEGORY: SETTINGS
- // OS: P
- NOTIFICATION_ZEN_MODE_DURATION_DIALOG = 1341;
-
- // OPEN: Settings > Date & time > Select time zone -> Region
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_REGION = 1355;
-
- // OPEN: Settings > Date & time > Select time zone -> Time Zone
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_TIME_ZONE = 1356;
- // OPEN: Settings > Date & time > Select time zone -> Select UTC Offset
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZONE_PICKER_FIXED_OFFSET = 1357;
-
- // OPEN: Settings > Gestures > Prevent Ringing
- // OS: P
- SETTINGS_PREVENT_RINGING = 1360;
-
- // Settings > Condition > Device muted
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_CONDITION_DEVICE_MUTED = 1368;
-
- // Settings > Condition > Device vibrate
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_CONDITION_DEVICE_VIBRATE = 1369;
-
- // OPEN: Settings > Connected devices > previously connected devices
- // CATEGORY: SETTINGS
- // OS: P
- PREVIOUSLY_CONNECTED_DEVICES = 1370;
-
- // OPEN: Settings > Network & Internet > Wi-Fi > Wi-Fi Preferences > Turn on Wi-Fi automatically
- // note: Wifi Scanning must be off for this dialog to show
- // CATEGORY: SETTINGS
- // OS: P
- WIFI_SCANNING_NEEDED_DIALOG = 1373;
-
- // OPEN: Settings > System > Gestures > System navigation
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_GESTURE_SWIPE_UP = 1374;
-
- // OPEN: Settings > Storage > Dialog to format a storage volume
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_VOLUME_FORMAT = 1375;
-
- // OPEN: DND onboarding activity
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_ZEN_ONBOARDING = 1380;
-
- // OPEN: Settings > Display > Auto brightness
- // CATEGORY: SETTINGS
- // OS: P
- SETTINGS_AUTO_BRIGHTNESS = 1381;
-
- // OPEN: Settings > Connected Devices > Bluetooth
- // CATEGORY: SETTINGS
- // OS: P
- BLUETOOTH_FRAGMENT = 1390;
-
- // Screen: DND Settings > Notifications
- // OS: P
- SETTINGS_ZEN_NOTIFICATIONS = 1400;
-
- // An event category for slices.
- // OPEN: Slice became visible.
- // CLOSE: Slice became invisible.
- // ACTION: Slice was tapped.
- SLICE = 1401;
-
- // OPEN: Settings -> Developer Options -> Disable Bluetooth A2DP hardware
- // offload
- // CATEGORY: SETTINGS
- // OS: P
- DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD = 1441;
-
- // OPEN: Settings homepage
- SETTINGS_HOMEPAGE = 1502;
-
- // OPEN: Settings > Create shortcut(widget)
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_CREATE_SHORTCUT = 1503;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_INTRO = 1506;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_ENROLLING = 1507;
-
- // OPEN: Face Enroll introduction
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_FINISHED = 1508;
-
- // OPEN: Face Enroll sidecar
- // CATEGORY: SETTINGS
- // OS: Q
- FACE_ENROLL_SIDECAR = 1509;
-
- // OPEN: Settings > Add face > Error dialog
- // OS: Q
- DIALOG_FACE_ERROR = 1510;
-
- // OPEN: Settings > Security > Face
- // CATEGORY: SETTINGS
- // OS: Q
- FACE = 1511;
-
- // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog
- // CATEGORY: SETTINGS
- // OS: Q
- DIALOG_ACCESSIBILITY_HEARINGAID = 1512;
-
- // OPEN: Settings > Add face
- // OS: Q
- FACE_ENROLL_PREVIEW = 1554;
-
- // OPEN: Settings > Network & Internet > Wi-Fi > Add network
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_WIFI_ADD_NETWORK = 1556;
-
- // OPEN: Settings > System > Input & Gesture > Reach up gesture
- // OS: Q
- SETTINGS_GESTURE_WAKE_LOCK_SCREEN = 1557;
-
- // OPEN: Settings > System > Input & Gesture > Wake screen
- SETTINGS_GESTURE_WAKE_SCREEN = 1570;
-
- // OPEN: Settings > Network & internet > Mobile network
- MOBILE_NETWORK = 1571;
-
- // OPEN: Settings > Network & internet > Mobile network > Choose network
- MOBILE_NETWORK_SELECT = 1581;
-
- // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog
- MOBILE_DATA_DIALOG = 1582;
-
- // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog
- MOBILE_ROAMING_DIALOG = 1583;
-
- // Settings > Display > Lock screen display > On lock screen
- LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
-
- // ConfirmDeviceCredentials > BiometricPrompt
- BIOMETRIC_FRAGMENT = 1585;
-
- // OPEN: Biometric Enrollment (android.settings.BIOMETRIC_ENROLL action intent)
- BIOMETRIC_ENROLL_ACTIVITY = 1586;
-
- // OPEN: Settings > Privacy
- TOP_LEVEL_PRIVACY = 1587;
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
- // Allow apps to override
- // CATEGORY: SETTINGS
- // OS: Q
- NOTIFICATION_ZEN_MODE_OVERRIDING_APPS = 1588;
-
-
- // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
- // Allow apps to override > Choose app
- // CATEGORY: SETTINGS
- // OS: Q
- NOTIFICATION_ZEN_MODE_OVERRIDING_APP = 1589;
-
- // OPEN: Settings > Developer options > Disable > Info dialog
- DIALOG_DISABLE_DEVELOPMENT_OPTIONS = 1591;
-
- // OPEN: WifiDppConfiguratorActivity (android.settings.WIFI_DPP_CONFIGURATOR_XXX action intents)
- SETTINGS_WIFI_DPP_CONFIGURATOR = 1595;
-
- // OPEN: WifiDppEnrolleeActivity (android.settings.WIFI_DPP_ENROLLEE_XXX action intents)
- SETTINGS_WIFI_DPP_ENROLLEE = 1596;
-
- // OPEN: Settings > Apps & Notifications -> Special app access -> Financial Apps Sms Access
- SETTINGS_FINANCIAL_APPS_SMS_ACCESS = 1597;
-
-
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_SETTINGS = 1604;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Custom
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_SOUND_SETTINGS = 1605;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_DEFAULT_SETTINGS = 1606;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS = 1608;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_VIS_EFFECTS = 1609;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom > Allow messages
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_MESSAGES = 1610;
-
- // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule)
- // > Do Not Disturb behavior > Use default Do Not Disturb behavior
- // > Notification restriction > Custom > Allow calls
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_RULE_CALLS = 1611;
-
- // OPEN: Settings > Sound > Do Not Disturb > Click footer link if custom settings applied
- // CATEGORY: SETTINGS
- // OS: Q
- ZEN_CUSTOM_SETTINGS_DIALOG = 1612;
-
- // OPEN: Settings > Developer Options > Graphics Driver Preferences
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_GRAPHICS_DRIVER_DASHBOARD = 1613;
-
- // OPEN: Settings > Accessibility > Vibration > Ring vibration
- // CATEGORY: SETTINGS
- // OS: Q
- ACCESSIBILITY_VIBRATION_RING = 1620;
-
- // OPEN: Settings > System > Input & Gesture > Skip songs
- SETTINGS_GESTURE_SKIP = 1624;
-
- // OPEN: Settings > System > Input & Gesture > Silence alerts
- SETTINGS_GESTURE_SILENCE = 1625;
-
- // OPEN: Settings > System > Input & Gesture > Tap to check
- SETTINGS_GESTURE_TAP_SCREEN = 1626;
-
- // OPEN: Settings > Network & internet > Click Mobile network to land on a page with a list of
- // SIM/eSIM subscriptions.
- MOBILE_NETWORK_LIST = 1627;
-
- // OPEN: Settings > Display > Adaptive sleep
- // OS: Q
- SETTINGS_ADAPTIVE_SLEEP = 1628;
-
- // OPEN: Settings > System > Aware
- SETTINGS_AWARE = 1632;
-
- // OPEN: Settings > System > Aware > Disable > Dialog
- DIALOG_AWARE_DISABLE = 1633;
-
- // OPEN: Settings > Settings > Network & internet > Click Mobile network to land on page with
- // details for a SIM/eSIM mobile network > Click edit icon to bring up a rename dialog.
- // OS: Q
- MOBILE_NETWORK_RENAME_DIALOG = 1642;
-
- // OPEN: Set new password (android.app.action.SET_NEW_PASSWORD action intent)
- // CATEGORY: SETTINGS
- // OS: Q
- SET_NEW_PASSWORD_ACTIVITY = 1644;
-
- // Panel for Internet Connectivity
- PANEL_INTERNET_CONNECTIVITY = 1654;
-
- // Panel for Volume
- PANEL_VOLUME = 1655;
-
- // Panel for NFC
- PANEL_NFC = 1656;
-
- // Panel for Media Output
- PANEL_MEDIA_OUTPUT = 1657;
-
- // Mapping: go/at-mapping
- PAGE_ATSSI = 1667;
-
- PAGE_ATSII = 1668;
-
- PAGE_ATUS = 1669;
-
- PAGE_ATSSP = 1670;
-
- PAGE_ATSAP = 1671;
-
- PAGE_ATSCP = 1672;
-
- PAGE_ATHNP = 1673;
-
- // OPEN: Accessibility detail settings (android.settings.ACCESSIBILITY_DETAILS_SETTINGS intent)
- ACCESSIBILITY_DETAILS_SETTINGS = 1682;
-
- // Open: Settings will show the conditional when Grayscale mode is on
- SETTINGS_CONDITION_GRAYSCALE_MODE = 1683;
-
- // Panel for Wifi
- PANEL_WIFI = 1687;
-
- // Open: Settings > Special App Access > Do not disturb control for app
- ZEN_ACCESS_DETAIL = 1692;
-
- // OPEN: Settings > Face > Remove face
- // OS: Q
- DIALOG_FACE_REMOVE = 1693;
-
- // Settings > Display > Theme
- DARK_UI_SETTINGS = 1698;
-
- // Settings > global bubble settings
- BUBBLE_SETTINGS = 1699;
-
- // Settings > app > bubble settings
- APP_BUBBLE_SETTINGS = 1700;
-
- // OPEN: Settings > System > Aware > Info dialog
- DIALOG_AWARE_STATUS = 1701;
-
- // Open: Settings > app > bubble settings > confirmation dialog
- DIALOG_APP_BUBBLE_SETTINGS = 1702;
-
- // OPEN: Settings > Pick SIM dialog
- DIALOG_SIM_LIST = 1707;
-
- // OPEN: Settings > Pick SIM (that supports calling) dialog
- DIALOG_CALL_SIM_LIST = 1708;
-
- // OPEN: Settings > Pick preferred SIM dialog
- DIALOG_PREFERRED_SIM_PICKER = 1709;
-
- // OPEN: Settings > Network & internet > Mobile network > Delete sim
- DIALOG_DELETE_SIM_CONFIRMATION = 1713;
-
- // OPEN: Settings > Network & internet > Mobile network > Delete sim > (answer yes to
- // confirmation)
- DIALOG_DELETE_SIM_PROGRESS = 1714;
-
- // Settings > Apps and notifications > Notifications > Gentle notifications
- GENTLE_NOTIFICATIONS_SCREEN = 1715;
-
- // OPEN: Settings > System > Gestures > Global Actions Panel
- // CATEGORY: SETTINGS
- // OS: Q
- GLOBAL_ACTIONS_PANEL_SETTINGS = 1728;
-
- // OPEN: Settings > Display > Dark Theme
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Only shows up on first time toggle
- DIALOG_DARK_UI_INFO = 1740;
-
- // OPEN: Settings > About phone > Legal information > Google Play system update licenses
- // CATEGORY: SETTINGS
- // OS: Q
- MODULE_LICENSES_DASHBOARD = 1746;
-
- // OPEN: Settings > System > Gestures > System navigation > Info icon
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Info icon is visible only when gesture navigation is not available and disabled
- SETTINGS_GESTURE_NAV_NOT_AVAILABLE_DLG = 1747;
-
- // OPEN: Settings > System > Gestures > System navigation > Gear icon
- // CATEGORY: SETTINGS
- // OS: Q
- // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
- SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
-
- // OPEN: Settings > System > Aware > Aware Display
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_AWARE_DISPLAY = 1750;
-
- // OPEN: Settings > System > Input & Gesture > tap gesture
- // CATEGORY: SETTINGS
- // OS: Q
- SETTINGS_GESTURE_TAP = 1751;
- // ---- End Q Constants, all Q constants go above this line ----
- // OPEN: Settings > Network & Internet > Wi-Fi > Click new network
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_WIFI_CONFIGURE_NETWORK = 1800;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: R
- // Note: Shows up only when Magnify with shortcut is enabled
- // and under accessibility button mode.
- DIALOG_TOGGLE_SCREEN_MAGNIFICATION_ACCESSIBILITY_BUTTON = 1801;
-
- // OPEN: Settings > Accessibility > Magnification
- // CATEGORY: SETTINGS
- // OS: R
- // Note: Shows up only when Magnify with shortcut is enabled.
- // and under gesture navigation mode.
- DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION = 1802;
-
- // OPEN: Settings > Security & screen lock -> Encryption & credentials > Install a certificate
- // CATEGORY: SETTINGS
- // OS: R
- INSTALL_CERTIFICATE_FROM_STORAGE = 1803;
-
- // OPEN: Settings > Apps and notifications > Special app access > notification access >
- // an app
- // CATEGORY: SETTINGS
- // OS: R
- NOTIFICATION_ACCESS_DETAIL = 1804;
-
- // OPEN: Settings > Developer Options > Platform Compat
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_PLATFORM_COMPAT_DASHBOARD = 1805;
-
- // OPEN: Settings > Location -> Work profile tab
- // CATEGORY: SETTINGS
- // OS: R
- LOCATION_WORK = 1806;
-
- // OPEN: Settings > Account -> Work profile tab
- // CATEGORY: SETTINGS
- // OS: R
- ACCOUNT_WORK = 1807;
-
- // OPEN: Settings > Developer Options > Bug report handler
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_BUGREPORT_HANDLER = 1808;
-
- // Panel for adding Wi-Fi networks
- // CATEGORY: SETTINGS
- // OS: R
- PANEL_ADD_WIFI_NETWORKS = 1809;
-
- // OPEN: Settings > Accessibility > Enable the feature or shortcut > Show tutorial dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_ACCESSIBILITY_TUTORIAL = 1810;
-
- // OPEN: Settings > Accessibility > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_ACCESSIBILITY_SERVICE_EDIT_SHORTCUT = 1812;
-
- // OPEN: Settings > Accessibility > Magnification > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_MAGNIFICATION_EDIT_SHORTCUT = 1813;
-
- // OPEN: Settings > Accessibility > Color correction > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_DALTONIZER_EDIT_SHORTCUT = 1814;
-
- // OPEN: Settings > Accessibility > Magnification > Settings
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_MAGNIFICATION_SETTINGS = 1815;
-
- // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_MAGNIFICATION_CAPABILITY = 1816;
-
- // OPEN: Settings > Accessibility > Color inversion
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_COLOR_INVERSION_SETTINGS = 1817;
-
- // OPEN: Settings > Accessibility > Color inversion > Edit shortcut dialog
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_COLOR_INVERSION_EDIT_SHORTCUT = 1818;
-
- // OPEN: Settings > Accessibility > Captions preference > Captions appearance
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_CAPTION_APPEARANCE = 1819;
-
- // OPEN: Settings > Accessibility > Captions preference > More options
- // CATEGORY: SETTINGS
- // OS: R
- ACCESSIBILITY_CAPTION_MORE_OPTIONS = 1820;
-
- // OPEN: Settings > Battery > Battery share
- // CATEGORY: SETTINGS
- // OS: R
- FUELGAUGE_BATTERY_SHARE = 1821;
-
- // OPEN: Settings -> Apps & Notifications -> Special App Access
- // CATEGORY: SETTINGS
- // OS: R
- MANAGE_EXTERNAL_STORAGE = 1822;
-
- // Open: Settings > DND > People
- // OS: R
- DND_PEOPLE = 1823;
-
- // OPEN: Settings > Apps and notifications > App info > one of any app > Open by default
- // > Open supported links
- // CATEGORY: SETTINGS
- // OS: R
- OPEN_SUPPORTED_LINKS = 1824;
-
- // OPEN: Settings > Display > Dark theme > Set start time dialog
- DIALOG_DARK_THEME_SET_START_TIME = 1825;
-
- // OPEN: Settings > Display > Dark theme > Set end time dialog
- DIALOG_DARK_THEME_SET_END_TIME = 1826;
-
- // OPEN: Settings -> Sound -> Vibrate for calls
- // CATEGORY: SETTINGS
- // OS: R
- VIBRATE_FOR_CALLS = 1827;
-
- // OPEN: Settings > Connected devices > Connection preferences > NFC
- // CATEGORY: SETTINGS
- // OS: R
- CONNECTION_DEVICE_ADVANCED_NFC = 1828;
-
- // OPEN: Settings -> Apps & Notifications -> Special App Access
- INTERACT_ACROSS_PROFILES = 1829;
-
- // OPEN: Settings > Notifications > (app or conversations) > conversation
- NOTIFICATION_CONVERSATION_SETTINGS = 1830;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // CATEGORY: SETTINGS
- // OS: R
- SETTINGS_ADB_WIRELESS = 1831;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Pair device with pairing code > Pairing code dialog
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_PAIRING_DIALOG = 1832;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Pair device with QR code > Scan QR code > Pairing device dialog
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_QR_PAIRING_DIALOG = 1833;
-
- // OPEN: Settings > apps & notifications > notifications > conversations
- // CATEGORY: SETTINGS
- // OS: R
- NOTIFICATION_CONVERSATION_LIST_SETTINGS = 1834;
-
- // Panel for Media Output Group operation
- // CATEGORY: SETTINGS
- // OS: R
- PANEL_MEDIA_OUTPUT_GROUP = 1835;
-
- // OPEN: Settings > Developer Options > Wireless debugging
- // > Click on paired device
- // CATEGORY: SETTINGS
- // OS: R
- ADB_WIRELESS_DEVICE_DETAILS = 1836;
-
- // Open: Settings > Sound > Do Not Disturb > People > Conversations
- // OS: R
- DND_CONVERSATIONS = 1837;
-
- // Open: Settings > Sound > Do Not Disturb > People > Calls
- // OS: R
- DND_CALLS = 1838;
-
- // Open: Settings > Sound > Do Not Disturb > People > Messages
- // OS: R
- DND_MESSAGES = 1839;
-
- // Open: Settings > Sound > Do Not Disturb > Apps > <Choose App>
- // OS: R
- DND_APPS_BYPASSING = 1840;
-
- // OPEN: Settings > System > Gestures > One-Handed
- // CATEGORY: SETTINGS
- // OS: R QPR
- SETTINGS_ONE_HANDED = 1841;
-
- // OPEN: Settings > Battery > Advanced battery option
- // CATEGORY: SETTINGS
- // OS: R
- FUELGAUGE_ADVANCED_BATTERY_OPTION = 1842;
-
- // OPEN: Settings > System > Gestures > Power menu
- // CATEGORY: SETTINGS
- // OS: R
- POWER_MENU_SETTINGS = 1843;
-
- // OPEN: Settings > System > Gestures > Power menu > Device controls
- // CATEGORY: SETTINGS
- // OS: R
- DEVICE_CONTROLS_SETTINGS = 1844;
-
- // OPEN: Settings > Sound > Media
- // CATEGORY: SETTINGS
- // OS: R
- MEDIA_CONTROLS_SETTINGS = 1845;
-
- // OPEN: Settings > System > Gestures > Swipe for notification
- // CATEGORY: SETTINGS
- // OS: R QPR
- SETTINGS_SWIPE_BOTTOM_TO_NOTIFICATION = 1846;
-
- // OPEN: Settings > System > Gestures > Emergency SOS Gesture
- // CATEGORY: SETTINGS
- // OS: S
- EMERGENCY_SOS_GESTURE_SETTINGS = 1847;
-
- // OPEN: Settings > System > Gestures > Double tap
- // CATEGORY: SETTINGS
- // OS: S
- SETTINGS_COLUMBUS = 1848;
-
- // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area > Magnification switch shortcut dialog
- // CATEGORY: SETTINGS
- // OS: S
- DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = 1849;
-
- // OPEN: Settings > Network & internet > Adaptive connectivity
- // CATEGORY: SETTINGS
- // OS: R QPR
- ADAPTIVE_CONNECTIVITY_CATEGORY = 1850;
-
- // OS: R QPR2
- BLUETOOTH_PAIRING_RECEIVER = 1851;
-
- // OPEN: Settings > Display > Screen timeout
- // CATEGORY: SETTINGS
- // OS: S
- SCREEN_TIMEOUT = 1852;
-
- // OPEN: Settings > Accessibility > Reduce Bright Colors
- // CATEGORY: SETTINGS
- // OS: S
- REDUCE_BRIGHT_COLORS_SETTINGS = 1853;
-
- // OPEN: Settings > Location > Time Zone Detection
- // CATEGORY: SETTINGS
- // OS: S
- LOCATION_TIME_ZONE_DETECTION = 1854;
-
- // OPEN: Settings > Developer options > Media transcode settings
- // CATEGORY: SETTINGS
- // OS: S
- TRANSCODE_SETTINGS = 1855;
-}
diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto
deleted file mode 100644
index 77bf98f1c15e..000000000000
--- a/core/proto/android/app/tvsettings_enums.proto
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.app.tvsettings;
-option java_multiple_files = true;
-option java_outer_classname = "TvSettingsEnums";
-
-/** The performed action types */
-enum Action {
-
- /**
- * Denotes an unknown action. It is a filler that should generally be
- * avoided.
- */
- ACTION_UNKNOWN = 0;
-
- /**
- * Denotes that a TvSettings page is being focused. (Previewing a page in
- * two panel settings should NOT be considered as focusing on the page.)
- */
- PAGE_FOCUSED = 1;
-
- /**
- * Denotes that an entry (typically a leaf node of settings tree) is
- * selected by a user.
- */
- ENTRY_SELECTED = 2;
-
- /** Denotes that a toggle is clicked by a user. */
- TOGGLE_INTERACTED = 3;
-
- /**
- * Denotes that a TvSettings page is being focused in the forward direction
- * into the settings tree.
- */
- PAGE_FOCUSED_FORWARD = 4;
-
- /**
- * Denotes that a TvSettings page is being focused in the backward direction
- * up the settings tree.
- */
- PAGE_FOCUSED_BACKWARD = 5;
-
- /** Denotes that a toggle is turned on by a user. */
- TOGGLED_ON = 6;
-
- /** Denotes that a toggle is turned off by a user. */
- TOGGLED_OFF = 7;
-
-}
-
-/**
- * Ids for TvSettings focusable pages or actionable entries
- *
- * For details of the scheme, please refer to the "Definition of item_id" and
- * "Evolve of item_id" sections in go/atv-settings-ww-logging-design.
- */
-enum ItemId {
-
- option allow_alias = true;
-
- // Filler that should be avoided
- UNKNOWN = 0x00000000;
-
- // TvSettings
- TV_SETTINGS_ROOT = 0x00000001;
-
- // TvSettings unknown/default classic page
- PAGE_CLASSIC_DEFAULT = 0x00000002;
-
- // TvSettings unknown/default slice page
- PAGE_SLICE_DEFAULT = 0x00000003;
-
- // TvSettings unknown/default entry
- ENTRY_DEFAULT = 0x00000004;
-
- // TvSettings > Suggested settings entry
- SUGGESTED_SETTINGS = 0x00000010;
-
- // TvSettings > Quick Settings
- QUICK_SETTINGS = 0x00000011;
-
- // VERSION 1: Starting with Q
- // These are ordered in depth-first search manner.
-
- // TvSettings > Network & Internet
- NETWORK = 0x11000000;
-
- // TvSettings > Network & Internet > Wi-Fi (toggle)
- NETWORK_WIFI_ON_OFF = 0x11100000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list]
- NETWORK_AP_INFO = 0x11200000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > Proxy settings
- NETWORK_AP_INFO_PROXY_SETTINGS = 0x11210000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > IP settings
- NETWORK_AP_INFO_IP_SETTINGS = 0x11220000;
-
- // TvSettings > Network & Internet >
- // [A connected network entry in available networks list] > Forget network
- NETWORK_AP_INFO_FORGET_NETWORK = 0x11230000;
-
- // TvSettings > Network & Internet >
- // [A not connected network entry in available networks list]
- NETWORK_NOT_CONNECTED_AP = 0x11300000;
-
- // TvSettings > Network & Internet > See all
- NETWORK_SEE_ALL = 0x11400000;
-
- // TvSettings > Network & Internet > See fewer
- NETWORK_SEE_FEWER = 0x11500000;
-
- // TvSettings > Network & Internet > Add new network
- NETWORK_ADD_NEW_NETWORK = 0x11600000;
-
- // TvSettings > Network & Internet > Scanning always available (toggle)
- NETWORK_ALWAYS_SCANNING_NETWORKS = 0x11700000;
-
- // TvSettings > Network & Internet > Proxy settings (in Ethernet category)
- NETWORK_ETHERNET_PROXY_SETTINGS = 0x11800000;
-
- // TvSettings > Network & Internet > IP settings (in Ethernet category)
- NETWORK_ETHERNET_IP_SETTINGS = 0x11900000;
-
- // TvSettings > Account & Sign In (Slice)
- ACCOUNT_SLICE = 0x12000000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account]
- ACCOUNT_SLICE_REG_ACCOUNT = 0x12100000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Services
- ACCOUNT_SLICE_REG_ACCOUNT_SERVICES = 0x12110000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Payment & Purchases
- ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT = 0x12120000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Payment & Purchases >
- // Require authentication for purchases (reauth interval)
- ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH = 0x12121000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Payment & Purchases >
- // Require authentication for purchases (reauth interval) > Always
- ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_ALWAYS = 0x12121100;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Payment & Purchases >
- // Require authentication for purchases (reauth interval) > Every 30 minutes
- ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_30MINS = 0x12121200;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Payment & Purchases >
- // Require authentication for purchases (reauth interval) > Never
- ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_NEVER = 0x12121300;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT = 0x12130000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > SafeSearch filter (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH = 0x12131000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Block offensive words (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Searchable apps
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS = 0x12133000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Google Assistant > Personal results (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_PERSONAL_RESULTS = 0x12134000;
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] >
- // Apps only mode (toggle)
- ACCOUNT_SLICE_REG_ACCOUNT_APPS_ONLY_MODE = 0x12140000;
-
- // Reserving [0x12150000, 0x12190000] for possible future settings
-
- // TvSettings > Account & Sign In (Slice) > [A regular account] > Remove
- ACCOUNT_SLICE_REG_ACCOUNT_REMOVE = 0x121A0000;
-
- // Reserving [0x12200000, 0x12900000] for possible future settings
-
- // TvSettings > Account & Sign In (Slice) > Add account...
- ACCOUNT_SLICE_ADD_ACCOUNT = 0x12A00000;
-
- // TvSettings > Account & Sign In (Classic)
- ACCOUNT_CLASSIC = 0x13000000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account]
- ACCOUNT_CLASSIC_REG_ACCOUNT = 0x13100000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] > Sync now
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_NOW = 0x13110000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // Remove account
- ACCOUNT_CLASSIC_REG_ACCOUNT_REMOVE_ACCOUNT = 0x13120000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Calendar (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CALENDAR = 0x13130000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Contacts (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CONTACTS = 0x13140000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Google Play Movies & TV (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPMT = 0x13150000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] Google Play Music (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPM = 0x13160000;
-
- // TvSettings > Account & Sign In (Classic) > [A regular account] >
- // [Choose synced apps] People details (toggle)
- ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_PEOPLE = 0x13170000;
-
- // Reserving [0x13200000, 0x13900000] for possible future settings
-
- // TvSettings > Account & Sign In (Classic) > Add account
- ACCOUNT_CLASSIC_ADD_ACCOUNT = 0x13A00000;
-
- // TvSettings > Privacy
- PRIVACY = 0x14000000;
-
- // TvSettings > Privacy > Location
- PRIVACY_LOCATION = 0x14100000;
-
- // TvSettings > Privacy > Location > Location status (radio button)
- PRIVACY_LOCATION_STATUS = 0x14110000;
-
- // TvSettings > Privacy > Location > Location status (radio button) >
- // Use Wi-Fi to estimate location
- PRIVACY_LOCATION_STATUS_USE_WIFI = 0x14111000;
-
- // TvSettings > Privacy > Location > Location status (radio button) > Off
- PRIVACY_LOCATION_STATUS_OFF = 0x14112000;
-
- // TvSettings > Privacy > Location > Scanning always available (toggle)
- PRIVACY_LOCATION_ALWAYS_SCANNING_NETWORKS = 0x14120000;
-
- // TvSettings > Privacy > Location > [An app that had recent requests]
- PRIVACY_LOCATION_REQUESTED_APP = 0x14130000;
-
- // TvSettings > Privacy > Usage & Diagnostics
- PRIVACY_DIAGNOSTICS = 0x14200000;
-
- // TvSettings > Privacy > Usage & Diagnostics > On (Toggle)
- PRIVACY_DIAGNOSTICS_ON_OFF = 0x14210000;
-
- // TvSettings > Privacy > Ads
- PRIVACY_ADS = 0x14300000;
-
- // The following three IDs may not actually be logged as they are within a
- // GMSCore Activity but we reserve IDs for them.
- // TvSettings > Privacy > Ads > Reset advertising ID
- PRIVACY_ADS_RESET_AD_ID = 0x14310000;
-
- // TvSettings > Privacy > Ads > Opt out of Ads Personalization
- PRIVACY_ADS_OPT_OUT_PERSONALIZATION = 0x14320000;
-
- // TvSettings > Privacy > Ads > Ads by Google (WebView)
- PRIVACY_ADS_ADS_BY_GOOGLE = 0x14330000;
-
- // TvSettings > Display & Sound
- DISPLAY_SOUND = 0x15000000;
-
- // TvSettings > Display & Sound > Advanced display settings
- DISPLAY_SOUND_ADVANCED_DISPLAY = 0x15100000;
-
- // TvSettings > Display & Sound > Advanced display settings >
- // Allow game mode (toggle)
- DISPLAY_SOUND_ADVANCED_DISPLAY_GAME_MODE = 0x15110000;
-
- // TvSettings > Display & Sound > System sounds (toggle)
- DISPLAY_SOUND_SYSTEM_SOUNDS = 0x15200000;
-
- // TvSettings > Display & Sound > Advanced sound settings
- DISPLAY_SOUND_ADVANCED_SOUNDS = 0x15300000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS = 0x15310000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // Auto...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_AUTO = 0x15311000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // None...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_NONE = 0x15312000;
-
- // TvSettings > Display & Sound > Advanced sound settings > Select formats >
- // Manual...
- DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_MANUAL = 0x15313000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby AC-4 (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DAC4 = 0x15320000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Atmos in Dolby Digital Plus (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DADDP = 0x15330000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Digital (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DD = 0x15340000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby Digital Plus (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DDP = 0x15350000;
-
- // TvSettings > Display & Sound > Advanced sound settings > DTS (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTS = 0x15360000;
-
- // TvSettings > Display & Sound > Advanced sound settings > DTS-HD (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTSHD = 0x15370000;
-
- // TvSettings > Display & Sound > Advanced sound settings > AAC (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_AAC = 0x15380000;
-
- // TvSettings > Display & Sound > Advanced sound settings >
- // Dolby TrueHD (toggle)
- DISPLAY_SOUND_ADVANCED_SOUNDS_DTHD = 0x15390000;
-
- // TvSettings > Apps
- APPS = 0x16000000;
-
- // TvSettings > Apps > See all apps
- APPS_ALL_APPS = 0x16100000;
-
- // TvSettings > Apps > See all apps > [An app entry]
- APPS_ALL_APPS_APP_ENTRY = 0x16110000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Open
- APPS_ALL_APPS_APP_ENTRY_OPEN = 0x16111000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Force stop
- APPS_ALL_APPS_APP_ENTRY_FORCE_STOP = 0x16112000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Uninstall
- APPS_ALL_APPS_APP_ENTRY_UNINSTALL = 0x16113000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Uninstall updates
- APPS_ALL_APPS_APP_ENTRY_UNINSTALL_UPDATES = 0x16114000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Disable
- APPS_ALL_APPS_APP_ENTRY_DISABLE = 0x16115000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear data
- APPS_ALL_APPS_APP_ENTRY_CLEAR_DATA = 0x16116000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear cache
- APPS_ALL_APPS_APP_ENTRY_CLEAR_CACHE = 0x16117000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Clear defaults
- APPS_ALL_APPS_APP_ENTRY_CLEAR_DEFAULTS = 0x16118000;
-
- // TvSettings > Apps > See all apps > [An app entry] >
- // Notifications (toggle)
- APPS_ALL_APPS_APP_ENTRY_NOTIFICATIONS = 0x16119000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Permissions
- APPS_ALL_APPS_APP_ENTRY_PERMISSIONS = 0x1611A000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Enable
- APPS_ALL_APPS_APP_ENTRY_ENABLE = 0x1611B000;
-
- // TvSettings > Apps > See all apps > [An app entry] > Open source licenses
- APPS_ALL_APPS_APP_ENTRY_LICENSES = 0x1611C000;
-
- // TvSettings > Apps > See all apps > Show system apps
- APPS_ALL_APPS_SHOW_SYSTEM_APPS = 0x16120000;
-
- // TvSettings > Apps > App permissions
- APPS_APP_PERMISSIONS = 0x16200000;
-
- // TvSettings > Apps > App permission > Body sensors
- APPS_APP_PERMISSIONS_BODY_SENSORS = 0x16210000;
-
- // TvSettings > Apps > App permission > Calendar
- APPS_APP_PERMISSIONS_CALENDAR = 0x16220000;
-
- // TvSettings > Apps > App permission > Call logs
- APPS_APP_PERMISSIONS_CALL_LOGS = 0x16230000;
-
- // TvSettings > Apps > App permission > Camera
- APPS_APP_PERMISSIONS_CAMERA = 0x16240000;
-
- // TvSettings > Apps > App permission > Contacts
- APPS_APP_PERMISSIONS_CONTACTS = 0x16250000;
-
- // TvSettings > Apps > App permission > Location
- APPS_APP_PERMISSIONS_LOCATION = 0x16260000;
-
- // TvSettings > Apps > App permission > Microphone
- APPS_APP_PERMISSIONS_MICROPHONE = 0x16270000;
-
- // TvSettings > Apps > App permission > Phone
- APPS_APP_PERMISSIONS_PHONE = 0x16280000;
-
- // TvSettings > Apps > App permission > Physical activity
- APPS_APP_PERMISSIONS_PHYSICAL_ACTIVITY = 0x16290000;
-
- // TvSettings > Apps > App permission > SMS
- APPS_APP_PERMISSIONS_SMS = 0x162A0000;
-
- // TvSettings > Apps > App permission > Storage
- APPS_APP_PERMISSIONS_STORAGE = 0x162B0000;
-
- // TvSettings > Apps > App permission > Additional permissions
- APPS_APP_PERMISSIONS_ADDITIONAL = 0x162C0000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // real all TV listings
- APPS_APP_PERMISSIONS_ADDITIONAL_READ_TV_LISTINGS = 0x162C1000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // real instant messages
- APPS_APP_PERMISSIONS_ADDITIONAL_READ_INSTANT_MESSAGES = 0x162C2000;
-
- // TvSettings > Apps > App permission > Additional permissions >
- // write instant messages
- APPS_APP_PERMISSIONS_ADDITIONAL_WRITE_INSTANT_MESSAGES = 0x162C3000;
-
- // TvSettings > Apps > Special app access
- APPS_SPECIAL_APP_ACCESS = 0x16300000;
-
- // TvSettings > Apps > Special app access > Energy optimization
- APPS_SPECIAL_APP_ACCESS_ENERGY_OPTIMIZATION = 0x16310000;
-
- // TvSettings > Apps > Special app access > Usage access
- APPS_SPECIAL_APP_ACCESS_USAGE_ACCESS = 0x16320000;
-
- // TvSettings > Apps > Special app access > Notification access
- APPS_SPECIAL_APP_ACCESS_NOTIFICATION_ACCESS = 0x16330000;
-
- // TvSettings > Apps > Special app access > Display over other apps
- APPS_SPECIAL_APP_ACCESS_DISPLAY_OVER_OTHERS = 0x16340000;
-
- // TvSettings > Apps > Special app access > Modify system settings
- APPS_SPECIAL_APP_ACCESS_MODIFY_SYSTEM_SETTINGS = 0x16350000;
-
- // TvSettings > Apps > Special app access > Picture-in-picture
- APPS_SPECIAL_APP_ACCESS_PICTURE_IN_PICTURE = 0x16360000;
-
- // TvSettings > Apps > Security & restrictions
- APPS_SECURITY_RESTRICTIONS = 0x16400000;
-
- // TvSettings > Apps > Security & restrictions > Unknown sources
- APPS_SECURITY_RESTRICTIONS_UNKNOWN_SOURCES = 0x16410000;
-
- // TvSettings > Apps > Security & restrictions > Verify apps (toggle)
- APPS_SECURITY_RESTRICTIONS_VERIFY_APPS = 0x16420000;
-
- // TvSettings > Apps > Security & restrictions > Create restricted profile
- APPS_SECURITY_RESTRICTIONS_CREATE_PROFILE = 0x16430000;
-
- // TvSettings > Apps > Security & restrictions > Enter restricted profile
- APPS_SECURITY_RESTRICTIONS_ENTER_PROFILE = 0x16440000;
-
- // TvSettings > Apps > Security & restrictions >
- // Allowed apps (Restricted Profile)
- APPS_SECURITY_RESTRICTIONS_PROFILE_ALLOWED_APPS = 0x16450000;
-
- // TvSettings > Apps > Security & restrictions >
- // Change pin (Restricted Profile)
- APPS_SECURITY_RESTRICTIONS_PROFILE_CHANGE_PIN = 0x16460000;
-
- // TvSettings > Apps > Security & restrictions >
- // Delete restricted profile
- APPS_SECURITY_RESTRICTIONS_DELETE_PROFILE = 0x16470000;
-
- // TvSettings > Apps > Security & restrictions >
- // Exit restricted profile
- APPS_SECURITY_RESTRICTIONS_EXIT_PROFILE = 0x16480000;
-
- // TvSettings > System (same as TvSettings > Device Preferences)
- SYSTEM = 0x17000000;
-
- // TvSettings > System > About
- SYSTEM_ABOUT = 0x17100000;
-
- // TvSettings > System > System update
- SYSTEM_ABOUT_SYSTEM_UPDATE = 0x17110000;
-
- // TvSettings > System > Device name
- SYSTEM_ABOUT_DEVICE_NAME = 0x17120000;
-
- // TvSettings > System > Factory reset
- SYSTEM_ABOUT_FACTORY_RESET = 0x17130000;
-
- // TvSettings > System > Status
- SYSTEM_ABOUT_STATUS = 0x17140000;
-
- // TvSettings > System > Legal information
- SYSTEM_ABOUT_LEGAL_INFO = 0x17150000;
-
- // TvSettings > System > Legal information > Open source licenses
- SYSTEM_ABOUT_LEGAL_INFO_OPEN_SOURCE = 0x17151000;
-
- // TvSettings > System > Legal information > Google legal
- SYSTEM_ABOUT_LEGAL_INFO_GOOGLE_LEGAL = 0x17152000;
-
- // TvSettings > System > Legal information > System WebView licenses
- SYSTEM_ABOUT_LEGAL_INFO_SYSTEM_WEBVIEW = 0x17153000;
-
- // TvSettings > System > Build
- SYSTEM_ABOUT_BUILD = 0x17160000;
-
- // TvSettings > System > Date & time
- SYSTEM_DATE_TIME = 0x17200000;
-
- // TvSettings > System > Date & time > Automatic data & time
- SYSTEM_DATE_TIME_AUTOMATIC = 0x17210000;
-
- // TvSettings > System > Date & time > Automatic data & time >
- // Use network-provided time
- SYSTEM_DATE_TIME_AUTOMATIC_USE_NETWORK_TIME = 0x17211000;
-
- // TvSettings > System > Date & time > Automatic data & time > Off
- SYSTEM_DATE_TIME_AUTOMATIC_OFF = 0x17212000;
-
- // TvSettings > System > Date & time > Set date
- SYSTEM_DATE_TIME_SET_DATE = 0x17220000;
-
- // TvSettings > System > Date & time > Set time
- SYSTEM_DATE_TIME_SET_TIME = 0x17230000;
-
- // TvSettings > System > Date & time > Set time zone
- SYSTEM_DATE_TIME_SET_TIME_ZONE = 0x17240000;
-
- // TvSettings > System > Date & time > Set time zone > [A time zone button]
- SYSTEM_DATE_TIME_SET_TIME_ZONE_BUTTON = 0x17241000;
-
- // TvSettings > System > Date & time > Use 24-hour format (toggle)
- SYSTEM_DATE_TIME_USE_24_HOUR_FORMAT = 0x17250000;
-
- // TvSettings > System > Language
- SYSTEM_LANGUAGE = 0x17300000;
-
- // TvSettings > System > Language > [A language button]
- SYSTEM_LANGUAGE_BUTTON = 0x17310000;
-
- // TvSettings > System > Keyboard
- SYSTEM_KEYBOARD = 0x17400000;
-
- // TvSettings > System > Keyboard > Current keyboard
- SYSTEM_KEYBOARD_CURRENT_KEYBOARD = 0x17410000;
-
- // TvSettings > System > Keyboard > Gboard Settings
- SYSTEM_KEYBOARD_GBOARD_SETTINGS = 0x17420000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Languages
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_LANGUAGES = 0x17421000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Terms of services
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_TOS = 0x17422000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Privacy policy
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_PRIVACY_POLICY = 0x17423000;
-
- // TvSettings > System > Keyboard > Gboard Settings > Open source licenses
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_OPEN_SOURCE = 0x17424000;
-
- // TvSettings > System > Keyboard > Gboard Settings >
- // Share usage statistics (toggle)
- SYSTEM_KEYBOARD_GBOARD_SETTINGS_SHARE_USAGE_STATS = 0x17425000;
-
- // TvSettings > System > Keyboard > Manage keyboards
- SYSTEM_KEYBOARD_MANAGE_KEYBOARDS = 0x17430000;
-
- // TvSettings > System > Storage
- SYSTEM_STORAGE = 0x17500000;
-
- // TvSettings > System > Internal shared storage
- SYSTEM_STORAGE_INTERNAL_STORAGE = 0x17510000;
-
- // TvSettings > System > Internal shared storage > Apps
- SYSTEM_STORAGE_INTERNAL_STORAGE_APPS = 0x17511000;
-
- // TvSettings > System > Internal shared storage >
- // Cached data (brings up "Clear cached data?" dialog upon click)
- SYSTEM_STORAGE_INTERNAL_STORAGE_CACHED = 0x17512000;
-
- // TvSettings > System > Ambient mode
- SYSTEM_AMBIENT = 0x17600000;
-
- // TvSettings > System > Ambient mode > Start now
- SYSTEM_AMBIENT_START = 0x17610000;
-
- // TvSettings > System > Ambient mode > Settings
- SYSTEM_AMBIENT_SETTINGS = 0x17620000;
-
- // TvSettings > System > Ambient mode > Settings > Google Photos (Channels)
- SYSTEM_AMBIENT_SETTINGS_CHANNEL_GP = 0x17621000;
-
- // TvSettings > System > Ambient mode > Settings > Art gallery (Channels)
- SYSTEM_AMBIENT_SETTINGS_CHANNEL_AG = 0x17622000;
-
- // TvSettings > System > Ambient mode > Settings >
- // Cinematic videos (Channels)
- SYSTEM_AMBIENT_SETTINGS_CHANNEL_CV = 0x17623000;
-
- // TvSettings > System > Ambient mode > Settings > Experimental (Channels)
- SYSTEM_AMBIENT_SETTINGS_CHANNEL_EXP = 0x17624000;
-
- // TvSettings > System > Ambient mode > Settings > Weather
- SYSTEM_AMBIENT_SETTINGS_WEATHER = 0x17625000;
-
- // TvSettings > System > Ambient mode > Settings > Weather > Hide
- SYSTEM_AMBIENT_SETTINGS_WEATHER_HIDE = 0x17625100;
-
- // TvSettings > System > Ambient mode > Settings > Weather > Celsius (Unit)
- SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_C = 0x17625200;
-
- // TvSettings > System > Ambient mode > Settings > Weather >
- // Fahrenheit (Unit)
- SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_F = 0x17625300;
-
- // TvSettings > System > Ambient mode > Settings > Weather > Both (Unit)
- SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_BOTH = 0x17625400;
-
- // TvSettings > System > Ambient mode > Settings > Time
- SYSTEM_AMBIENT_SETTINGS_TIME = 0x17626000;
-
- // TvSettings > System > Ambient mode > Settings > Time > Hide
- SYSTEM_AMBIENT_SETTINGS_TIME_HIDE = 0x17626100;
-
- // TvSettings > System > Ambient mode > Settings > Time > Show
- SYSTEM_AMBIENT_SETTINGS_TIME_SHOW = 0x17626200;
-
- // TvSettings > System > Ambient mode > Settings > Device information
- SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO = 0x17627000;
-
- // TvSettings > System > Ambient mode > Settings > Device information > Hide
- SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO_HIDE = 0x17627100;
-
- // TvSettings > System > Ambient mode > Settings > Device information > Show
- SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO_SHOW = 0x17627200;
-
- // TvSettings > System > Ambient mode > Settings > Personal photo data
- SYSTEM_AMBIENT_SETTINGS_PPD = 0x17628000;
-
- // TvSettings > System > Ambient mode > Settings > Personal photo data >
- // Hide
- SYSTEM_AMBIENT_SETTINGS_PPD_HIDE = 0x17628100;
-
- // TvSettings > System > Ambient mode > Settings > Personal photo data >
- // Show
- SYSTEM_AMBIENT_SETTINGS_PPD_SHOW = 0x17628200;
-
- // TvSettings > System > Ambient mode > Settings > Portrait Google Photos
- SYSTEM_AMBIENT_SETTINGS_PGP = 0x17629000;
-
- // TvSettings > System > Ambient mode > Settings > Portrait Google Photos >
- // Hide
- SYSTEM_AMBIENT_SETTINGS_PGP_HIDE = 0x17629100;
-
- // TvSettings > System > Ambient mode > Settings > Portrait Google Photos >
- // Show
- SYSTEM_AMBIENT_SETTINGS_PGP_SHOW = 0x17629200;
-
- // TvSettings > System > Ambient mode > Settings > Portrait Google Photos >
- // Show pairs
- SYSTEM_AMBIENT_SETTINGS_PGP_SHOW_PAIRS = 0x17629300;
-
- // TvSettings > System > Ambient mode > Settings > Personal photo curation
- SYSTEM_AMBIENT_SETTINGS_PPC = 0x1762A000;
-
- // TvSettings > System > Ambient mode > Settings > Personal photo curation >
- // All albums
- SYSTEM_AMBIENT_SETTINGS_PPC_ALL_ALBUMS = 0x1762A100;
-
- // TvSettings > System > Ambient mode > Settings > Personal photo curation >
- // Live albums only
- SYSTEM_AMBIENT_SETTINGS_PPC_LIVE_ALBUMS = 0x1762A200;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED = 0x1762B000;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 5s
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_5S = 0x1762B100;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 10s
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_10S = 0x1762B200;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 30s
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_30S = 0x1762B300;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 1m
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_1M = 0x1762B400;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 3m
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_3M = 0x1762B500;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 5m
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_5M = 0x1762B600;
-
- // TvSettings > System > Ambient mode > Settings > Slideshow speed > 10m
- SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_10M = 0x1762B700;
-
- // TvSettings > System > Energy saver
- SYSTEM_ENERGYSAVER = 0x17700000;
-
- // TvSettings > System > Energy saver > Turn off display after
- SYSTEM_ENERGYSAVER_START_DELAY = 0x17710000;
-
- // TvSettings > System > Energy saver > Turn off display after > 15 minutes
- SYSTEM_ENERGYSAVER_START_DELAY_15M = 0x17711000;
-
- // TvSettings > System > Energy saver > Turn off display after > 30 minutes
- SYSTEM_ENERGYSAVER_START_DELAY_30M = 0x17712000;
-
- // TvSettings > System > Energy saver > Turn off display after > 1 hour
- SYSTEM_ENERGYSAVER_START_DELAY_1H = 0x17713000;
-
- // TvSettings > System > Energy saver > Turn off display after > 3 hours
- SYSTEM_ENERGYSAVER_START_DELAY_3H = 0x17714000;
-
- // TvSettings > System > Energy saver > Turn off display after > 6 hours
- SYSTEM_ENERGYSAVER_START_DELAY_6H = 0x17715000;
-
- // TvSettings > System > Energy saver > Turn off display after > 12 hours
- SYSTEM_ENERGYSAVER_START_DELAY_12H = 0x17716000;
-
- // TvSettings > System > Energy saver > Turn off display after > Never
- SYSTEM_ENERGYSAVER_START_DELAY_NEVER = 0x17717000;
-
- // TvSettings > System > Accessibility
- SYSTEM_A11Y = 0x17800000;
-
- // TvSettings > System > Accessibility > Captions
- SYSTEM_A11Y_CAPTIONS = 0x17810000;
-
- // TvSettings > System > Accessibility > Captions > Display (toggle)
- SYSTEM_A11Y_CAPTIONS_DISPLAY_ON_OFF = 0x17811000;
-
- // TvSettings > System > Accessibility > Captions > Language
- SYSTEM_A11Y_CAPTIONS_LANGUAGE = 0x17812000;
-
- // TvSettings > System > Accessibility > Captions > Language > [A language]
- SYSTEM_A11Y_CAPTIONS_LANGUAGE_BUTTON = 0x17812100;
-
- // TvSettings > System > Accessibility > Captions > Text size
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE = 0x17813000;
-
- // TvSettings > System > Accessibility > Captions > Text size > Very small
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_SMALL = 0x17813100;
-
- // TvSettings > System > Accessibility > Captions > Text size > Small
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_SMALL = 0x17813200;
-
- // TvSettings > System > Accessibility > Captions > Text size > Normal
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_NORMAL = 0x17813300;
-
- // TvSettings > System > Accessibility > Captions > Text size > Large
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_LARGE = 0x17813400;
-
- // TvSettings > System > Accessibility > Captions > Text size > Very large
- SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_LARGE = 0x17813500;
-
- // TvSettings > System > Accessibility > Captions >
- // White on black (radio button)
- SYSTEM_A11Y_CAPTIONS_WHITE_ON_BLACK = 0x17814000;
-
- // TvSettings > System > Accessibility > Captions >
- // Black on white (radio button)
- SYSTEM_A11Y_CAPTIONS_BLACK_ON_WHITE = 0x17815000;
-
- // TvSettings > System > Accessibility > Captions >
- // Yellow on black (radio button)
- SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLACK = 0x17816000;
-
- // TvSettings > System > Accessibility > Captions >
- // Yellow on blue (radio button)
- SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLUE = 0x17817000;
-
- // TvSettings > System > Accessibility > Captions > Custom
- SYSTEM_A11Y_CAPTIONS_CUSTOM = 0x17818000;
-
- // TvSettings > System > Accessibility > Captions > Custom > Font family
- SYSTEM_A11Y_CAPTIONS_CUSTOM_FONT = 0x17818100;
-
- // TvSettings > System > Accessibility > Captions > Custom > Text color
- SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_COLOR = 0x17818200;
-
- // TvSettings > System > Accessibility > Captions > Custom > Text opacity
- SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_OPACITY = 0x17818300;
-
- // TvSettings > System > Accessibility > Captions > Custom > Edge type
- SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_TYPE = 0x17818400;
-
- // TvSettings > System > Accessibility > Captions > Custom > Edge color
- SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_COLOR = 0x17818500;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Show background (toggle)
- SYSTEM_A11Y_CAPTIONS_SHOW_BACKGROUND = 0x17818600;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Background color
- SYSTEM_A11Y_CAPTIONS_BACKGROUND_COLOR = 0x17818700;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Background opacity
- SYSTEM_A11Y_CAPTIONS_BACKGROUND_OPACITY = 0x17818800;
-
- // TvSettings > System > Accessibility > Captions > Custom >
- // Show window (toggle)
- SYSTEM_A11Y_CAPTIONS_SHOW_WINDOW = 0x17818900;
-
- // TvSettings > System > Accessibility > Captions > Custom > Window color
- SYSTEM_A11Y_CAPTIONS_WINDOW_COLOR = 0x17818A00;
-
- // TvSettings > System > Accessibility > Captions > Custom > Window opacity
- SYSTEM_A11Y_CAPTIONS_WINDOW_OPACITY = 0x17818B00;
-
- // TvSettings > System > Accessibility > High contrast text (toggle)
- SYSTEM_A11Y_HIGH_CONTRAST_TEXT = 0x17820000;
-
- // TvSettings > System > Accessibility > Text to speech
- SYSTEM_A11Y_TTS = 0x17830000;
-
- // TvSettings > System > Accessibility > Text to speech > [Select an engine]
- SYSTEM_A11Y_TTS_ENGINE_SELECT = 0x17831000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration
- SYSTEM_A11Y_TTS_ENGINE_CONFIG = 0x17832000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Language
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE = 0x17832100;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Language > Button
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE_CHOOSE_LANGUAGE = 0x17832110;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Settings for Google Text-to-speech Engine
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_SETTINGS_GTTS_ENGINE = 0x17832200;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Engine configuration > Install voice data
- SYSTEM_A11Y_TTS_ENGINE_CONFIG_INSTALL_VOICE_DATA = 0x17832300;
-
- // TvSettings > System > Accessibility > Text to speech > Speech rate
- SYSTEM_A11Y_TTS_SPEECH_RATE = 0x17833000;
-
- // TvSettings > System > Accessibility > Text to speech >
- // Listen to an example
- SYSTEM_A11Y_TTS_LISTEN_EXAMPLE = 0x17834000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut
- SYSTEM_A11Y_SHORTCUT = 0x17840000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut >
- // Enable (toggle)
- SYSTEM_A11Y_SHORTCUT_ON_OFF = 0x17841000;
-
- // TvSettings > System > Accessibility > Accessibility shortcut >
- // Shortcut services
- SYSTEM_A11Y_SHORTCUT_SERVICE = 0x17842000;
-
- // TvSettings > System > Accessibility > TalkBack
- SYSTEM_A11Y_TALKBACK = 0x17850000;
-
- // TvSettings > System > Accessibility > TalkBack > Enable (toggle)
- SYSTEM_A11Y_TALKBACK_ON_OFF = 0x17851000;
-
- // TvSettings > System > Accessibility > TalkBack > Configuration
- SYSTEM_A11Y_TALKBACK_CONFIG = 0x17852000;
-
- // TvSettings > System > Accessibility > Accessibility Menu
- SYSTEM_A11Y_A11Y_MENU = 0x17860000;
-
- // TvSettings > System > Accessibility > Accessibility Menu >
- // Enable (toggle)
- SYSTEM_A11Y_A11Y_MENU_ON_OFF = 0x17861000;
-
- // TvSettings > System > Accessibility > Accessibility Menu > Configuration
- SYSTEM_A11Y_A11Y_MENU_CONFIG = 0x17862000;
-
- // TvSettings > System > Accessibility > Select to Speak
- SYSTEM_A11Y_STS = 0x17870000;
-
- // TvSettings > System > Accessibility > Select to Speak > Enable (toggle)
- SYSTEM_A11Y_STS_ON_OFF = 0x17871000;
-
- // TvSettings > System > Accessibility > Select to Speak > Configuration
- SYSTEM_A11Y_STS_CONFIG = 0x17872000;
-
- // TvSettings > System > Accessibility > Switch Access
- SYSTEM_A11Y_SWITCH_ACCESS = 0x17880000;
-
- // TvSettings > System > Accessibility > Switch Access > Enable (Toggle)
- SYSTEM_A11Y_SWITCH_ACCESS_ON_OFF = 0x17881000;
-
- // TvSettings > System > Accessibility > Switch Access > Configuration
- SYSTEM_A11Y_SWITCH_ACCESS_CONFIG = 0x17882000;
-
- // TvSettings > System > Reboot
- SYSTEM_REBOOT = 0x17900000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings)
- PREFERENCES_HOME_SCREEN = 0x17A00000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS = 0x17A10000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN = 0x17A11000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > On (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_ON_OFF = 0x17A11100;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Google Play Movies & TV (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPMT = 0x17A11200;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Google Play Music (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPM = 0x17A11300;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Play Next > Promotional channels (toggle)
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_PROMOTIONAL = 0x17A11400;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Home screen channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_HOME_SCREEN = 0x17A12000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Customize channels > Promotional channels
- PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PROMOTIONAL = 0x17A13000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Enable video previews (toggle)
- PREFERENCES_HOME_SCREEN_VIDEO_PREVIEWS = 0x17A20000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Enable audio previews (toggle)
- PREFERENCES_HOME_SCREEN_AUDIO_PREVIEWS = 0x17A30000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Reorder apps
- PREFERENCES_HOME_SCREEN_REORDER_APPS = 0x17A40000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Reorder games
- PREFERENCES_HOME_SCREEN_REORDER_GAMES = 0x17A50000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Android TV Home open source licenses
- PREFERENCES_HOME_SCREEN_ATVH_OPEN_SOURCE = 0x17A60000;
-
- // TvSettings > Device Preferences > Home screen (in classic TvSettings) >
- // Android TV Core Services open source licenses
- PREFERENCES_HOME_SCREEN_ATVCS_OPEN_SOURCE = 0x17A70000;
-
- // TvSettings > Device Preferences > Google Assistant
- PREFERENCES_ASSISTANT = 0x17B00000;
-
- // TvSettings > Device Preferences > Google Assistant > Accounts
- PREFERENCES_ASSISTANT_ACCOUNTS = 0x17B10000;
-
- // TvSettings > Device Preferences > Google Assistant > Accept permissions
- PREFERENCES_ASSISTANT_ACCEPT_PERMISSIONS = 0x17B20000;
-
- // TvSettings > Device Preferences > Google Assistant > View permissions
- PREFERENCES_ASSISTANT_VIEW_PERMISSIONS = 0x17B30000;
-
- // TvSettings > Device Preferences > Google Assistant > Searchable apps
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS)
- PREFERENCES_ASSISTANT_SEARCHABLE_APPS = 0x12133000;
-
- // TvSettings > Device Preferences > Google Assistant > SafeSearch filter
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH)
- PREFERENCES_ASSISTANT_SAFESEARCH_FILTER = 0x12131000;
-
- // TvSettings > Device Preferences > Google Assistant >
- // Block offensive words
- // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE)
- PREFERENCES_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000;
-
- // TvSettings > Device Preferences > Google Assistant > Open source licenses
- PREFERENCES_ASSISTANT_OPEN_SOURCE = 0x17B40000;
-
- // TvSettings > Device Preferences > Chromecast Android Shell
- PREFERENCES_CHROMECAST_SHELL = 0x17C00000;
-
- // TvSettings > Device Preferences > Chromecast Android Shell >
- // Open source licenses
- PREFERENCES_CHROMECAST_SHELL_OPEN_SOURCE = 0x17C10000;
-
- // TvSettings > Device Preferences > Screen saver
- PREFERENCES_SCREENSAVER = 0x17D00000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser)
- PREFERENCES_SCREENSAVER_CHOOSER = 0x17D10000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Turn screen off
- PREFERENCES_SCREENSAVER_CHOOSER_SCREEN_OFF = 0x17D11000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Backdrop
- PREFERENCES_SCREENSAVER_CHOOSER_BACKDROP = 0x17D12000;
-
- // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) >
- // Colors
- PREFERENCES_SCREENSAVER_CHOOSER_COLORS = 0x17D13000;
-
- // TvSettings > Device Preferences > Screen saver > When to start
- PREFERENCES_SCREENSAVER_START_DELAY = 0x17D20000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 5 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_5M = 0x17D21000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 15 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_15M = 0x17D22000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 30 minutes
- PREFERENCES_SCREENSAVER_START_DELAY_30M = 0x17D23000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 1 hour
- PREFERENCES_SCREENSAVER_START_DELAY_1H = 0x17D24000;
-
- // TvSettings > Device Preferences > Screen saver > When to start >
- // 2 hours
- PREFERENCES_SCREENSAVER_START_DELAY_2H = 0x17D25000;
-
- // TvSettings > Device Preferences > Screen saver > Start now
- PREFERENCES_SCREENSAVER_START_NOW = 0x17D30000;
-
- // TvSettings > Connected Devices (Slice)
- CONNECTED_SLICE = 0x18000000;
-
- // TvSettings > Connected Devices (Slice) > Connect remote or headphones
- CONNECTED_SLICE_CONNECT_NEW_DEVICES = 0x18100000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device]
- CONNECTED_SLICE_DEVICE_ENTRY = 0x18200000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] >
- // Remote update
- CONNECTED_SLICE_DEVICE_ENTRY_UPDATE = 0x18210000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] > Rename
- CONNECTED_SLICE_DEVICE_ENTRY_RENAME = 0x18220000;
-
- // TvSettings > Connected Devices (Slice) > [A connected device] > Forget
- CONNECTED_SLICE_DEVICE_ENTRY_FORGET = 0x18230000;
-
- // TvSettings > Connected Devices (Slice) > HDMI-CEC
- CONNECTED_SLICE_HDMICEC = 0x18300000;
-
- // TvSettings > Connected Devices (Slice) > HDMI-CEC > Enable (toggle)
- CONNECTED_SLICE_HDMICEC_ON_OFF = 0x18310000;
-
- // TvSettings > Connected Devices (aliasing CONNECTED_SLICE)
- CONNECTED_CLASSIC = 0x18000000;
-
- // TvSettings > Connected Devices > Connect remote
- // (aliasing CONNECTED_SLICE_CONNECT_NEW_DEVICES)
- CONNECTED_CLASSIC_CONNECT_REMOTE = 0x18100000;
-
- // TvSettings > Connected Devices > [A connected device]
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY)
- CONNECTED_CLASSIC_DEVICE_ENTRY = 0x18200000;
-
- // TvSettings > Connected Devices > [A connected device] > Update
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_UPDATE)
- CONNECTED_CLASSIC_DEVICE_ENTRY_UPDATE = 0x18210000;
-
- // TvSettings > Connected Devices > [A connected device] > Rename
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_RENAME)
- CONNECTED_CLASSIC_DEVICE_ENTRY_RENAME = 0x18220000;
-
- // TvSettings > Connected Devices > [A connected device] > Forget
- // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_FORGET)
- CONNECTED_CLASSIC_DEVICE_ENTRY_FORGET = 0x18230000;
-
- // TvSettings > Connected Devices > HDMI-CEC
- // (aliasing CONNECTED_SLICE_HDMICEC)
- CONNECTED_CLASSIC_HDMICEC = 0x18300000;
-
- // TvSettings > Connected Devices > HDMI-CEC > Enable (toggle)
- // (aliasing CONNECTED_SLICE_HDMICEC_ON_OFF)
- CONNECTED_CLASSIC_HDMICEC_ON_OFF = 0x18310000;
-
- // TvSettings > Help & Feedback
- FEEDBACK = 0x19000000;
-
- // TvSettings > Help & Feedback > Send feedback
- FEEDBACK_SEND = 0x19100000;
-}
diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto
deleted file mode 100644
index dc60ededf965..000000000000
--- a/core/proto/android/bluetooth/enums.proto
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth;
-
-option java_outer_classname = "BluetoothProtoEnums";
-option java_multiple_files = true;
-
-// Bluetooth connection states.
-enum ConnectionStateEnum {
- CONNECTION_STATE_DISCONNECTED = 0;
- CONNECTION_STATE_CONNECTING = 1;
- CONNECTION_STATE_CONNECTED = 2;
- CONNECTION_STATE_DISCONNECTING = 3;
-}
-
-// Bluetooth Adapter Enable and Disable Reasons
-enum EnableDisableReasonEnum {
- ENABLE_DISABLE_REASON_UNSPECIFIED = 0;
- ENABLE_DISABLE_REASON_APPLICATION_REQUEST = 1;
- ENABLE_DISABLE_REASON_AIRPLANE_MODE = 2;
- ENABLE_DISABLE_REASON_DISALLOWED = 3;
- ENABLE_DISABLE_REASON_RESTARTED = 4;
- ENABLE_DISABLE_REASON_START_ERROR = 5;
- ENABLE_DISABLE_REASON_SYSTEM_BOOT = 6;
- ENABLE_DISABLE_REASON_CRASH = 7;
- ENABLE_DISABLE_REASON_USER_SWITCH = 8;
- ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9;
- ENABLE_DISABLE_REASON_FACTORY_RESET = 10;
- ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED = 11;
-}
-
-enum DirectionEnum {
- DIRECTION_UNKNOWN = 0;
- DIRECTION_OUTGOING = 1;
- DIRECTION_INCOMING = 2;
-}
-
-// First item is the default value, other values follow Bluetooth spec definition
-enum LinkTypeEnum {
- // Link type is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- LINK_TYPE_UNKNOWN = 0xFFF;
- LINK_TYPE_SCO = 0x00;
- LINK_TYPE_ACL = 0x01;
- LINK_TYPE_ESCO = 0x02;
-}
-
-enum DeviceInfoSrcEnum {
- DEVICE_INFO_SRC_UNKNOWN = 0;
- // Within Android Bluetooth stack
- DEVICE_INFO_INTERNAL = 1;
- // Outside Android Bluetooth stack
- DEVICE_INFO_EXTERNAL = 2;
-}
-
-enum DeviceTypeEnum {
- DEVICE_TYPE_UNKNOWN = 0;
- DEVICE_TYPE_CLASSIC = 1;
- DEVICE_TYPE_LE = 2;
- DEVICE_TYPE_DUAL = 3;
-}
-
-// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
-enum TransportTypeEnum {
- TRANSPORT_TYPE_AUTO = 0;
- TRANSPORT_TYPE_BREDR = 1;
- TRANSPORT_TYPE_LE = 2;
-}
-
-// Bond state enum
-// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
-enum BondStateEnum {
- BOND_STATE_UNKNOWN = 0;
- BOND_STATE_NONE = 10;
- BOND_STATE_BONDING = 11;
- BOND_STATE_BONDED = 12;
-}
-
-// Sub states within the bonding general state
-enum BondSubStateEnum {
- BOND_SUB_STATE_UNKNOWN = 0;
- BOND_SUB_STATE_LOCAL_OOB_DATA_PROVIDED = 1;
- BOND_SUB_STATE_LOCAL_PIN_REQUESTED = 2;
- BOND_SUB_STATE_LOCAL_PIN_REPLIED = 3;
- BOND_SUB_STATE_LOCAL_SSP_REQUESTED = 4;
- BOND_SUB_STATE_LOCAL_SSP_REPLIED = 5;
-}
-
-enum UnbondReasonEnum {
- UNBOND_REASON_UNKNOWN = 0;
- UNBOND_REASON_AUTH_FAILED = 1;
- UNBOND_REASON_AUTH_REJECTED = 2;
- UNBOND_REASON_AUTH_CANCELED = 3;
- UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
- UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
- UNBOND_REASON_AUTH_TIMEOUT = 6;
- UNBOND_REASON_REPEATED_ATTEMPTS = 7;
- UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
- UNBOND_REASON_REMOVED = 9;
-}
-
-enum SocketTypeEnum {
- SOCKET_TYPE_UNKNOWN = 0;
- SOCKET_TYPE_RFCOMM = 1;
- SOCKET_TYPE_SCO = 2;
- SOCKET_TYPE_L2CAP_BREDR = 3;
- SOCKET_TYPE_L2CAP_LE = 4;
-}
-
-enum SocketConnectionstateEnum {
- SOCKET_CONNECTION_STATE_UNKNOWN = 0;
- // Socket acts as a server waiting for connection
- SOCKET_CONNECTION_STATE_LISTENING = 1;
- // Socket acts as a client trying to connect
- SOCKET_CONNECTION_STATE_CONNECTING = 2;
- // Socket is connected
- SOCKET_CONNECTION_STATE_CONNECTED = 3;
- // Socket tries to disconnect from remote
- SOCKET_CONNECTION_STATE_DISCONNECTING = 4;
- // This socket is closed
- SOCKET_CONNECTION_STATE_DISCONNECTED = 5;
-}
-
-enum SocketRoleEnum {
- SOCKET_ROLE_UNKNOWN = 0;
- SOCKET_ROLE_LISTEN = 1;
- SOCKET_ROLE_CONNECTION = 2;
-}
diff --git a/core/proto/android/bluetooth/hci/enums.proto b/core/proto/android/bluetooth/hci/enums.proto
deleted file mode 100644
index ef894e548351..000000000000
--- a/core/proto/android/bluetooth/hci/enums.proto
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.hci;
-
-option java_outer_classname = "BluetoothHciProtoEnums";
-option java_multiple_files = true;
-
-// HCI command opcodes (OCF+OGF) from Bluetooth 5.0 specification Vol 2, Part E, Section 7
-// Original definition: system/bt/stack/include/hcidefs.h
-enum CommandEnum {
- // Opcode is at most 2 bytes (0xFFFF), thus 0xFFFFF must not be a valid value
- CMD_UNKNOWN = 0xFFFFF;
- // Link control commands 0x0400
- CMD_INQUIRY = 0x0401;
- CMD_INQUIRY_CANCEL = 0x0402;
- CMD_PERIODIC_INQUIRY_MODE = 0x0403;
- CMD_EXIT_PERIODIC_INQUIRY_MODE = 0x0404;
- CMD_CREATE_CONNECTION = 0x0405;
- CMD_DISCONNECT = 0x0406;
- CMD_ADD_SCO_CONNECTION = 0x0407; // Deprecated since Bluetooth 1.2
- CMD_CREATE_CONNECTION_CANCEL = 0x0408;
- CMD_ACCEPT_CONNECTION_REQUEST = 0x0409;
- CMD_REJECT_CONNECTION_REQUEST = 0x040A;
- CMD_LINK_KEY_REQUEST_REPLY = 0x040B;
- CMD_LINK_KEY_REQUEST_NEG_REPLY = 0x040C;
- CMD_PIN_CODE_REQUEST_REPLY = 0x040D;
- CMD_PIN_CODE_REQUEST_NEG_REPLY = 0x040E;
- CMD_CHANGE_CONN_PACKET_TYPE = 0x040F;
- CMD_AUTHENTICATION_REQUESTED = 0x0411;
- CMD_SET_CONN_ENCRYPTION = 0x0413;
- CMD_CHANGE_CONN_LINK_KEY = 0x0415;
- CMD_MASTER_LINK_KEY = 0x0417;
- CMD_RMT_NAME_REQUEST = 0x0419;
- CMD_RMT_NAME_REQUEST_CANCEL = 0x041A;
- CMD_READ_RMT_FEATURES = 0x041B;
- CMD_READ_RMT_EXT_FEATURES = 0x041C;
- CMD_READ_RMT_VERSION_INFO = 0x041D;
- CMD_READ_RMT_CLOCK_OFFSET = 0x041F;
- CMD_READ_LMP_HANDLE = 0x0420;
- CMD_SETUP_ESCO_CONNECTION = 0x0428;
- CMD_ACCEPT_ESCO_CONNECTION = 0x0429;
- CMD_REJECT_ESCO_CONNECTION = 0x042A;
- CMD_IO_CAPABILITY_REQUEST_REPLY = 0x042B;
- CMD_USER_CONF_REQUEST_REPLY = 0x042C;
- CMD_USER_CONF_VALUE_NEG_REPLY = 0x042D;
- CMD_USER_PASSKEY_REQ_REPLY = 0x042E;
- CMD_USER_PASSKEY_REQ_NEG_REPLY = 0x042F;
- CMD_REM_OOB_DATA_REQ_REPLY = 0x0430;
- CMD_REM_OOB_DATA_REQ_NEG_REPLY = 0x0433;
- CMD_IO_CAP_REQ_NEG_REPLY = 0x0434;
- // BEGIN: AMP commands (not used in system/bt)
- CMD_CREATE_PHYSICAL_LINK = 0x0435;
- CMD_ACCEPT_PHYSICAL_LINK = 0x0436;
- CMD_DISCONNECT_PHYSICAL_LINK = 0x0437;
- CMD_CREATE_LOGICAL_LINK = 0x0438;
- CMD_ACCEPT_LOGICAL_LINK = 0x0439;
- CMD_DISCONNECT_LOGICAL_LINK = 0x043A;
- CMD_LOGICAL_LINK_CANCEL = 0x043B;
- CMD_FLOW_SPEC_MODIFY = 0x043C;
- // END: AMP commands
- CMD_ENH_SETUP_ESCO_CONNECTION = 0x043D;
- CMD_ENH_ACCEPT_ESCO_CONNECTION = 0x043E;
- CMD_TRUNCATED_PAGE = 0x043F;
- CMD_TRUNCATED_PAGE_CANCEL = 0x0440;
- CMD_SET_CLB = 0x0441;
- CMD_RECEIVE_CLB = 0x0442;
- CMD_START_SYNC_TRAIN = 0x0443;
- CMD_RECEIVE_SYNC_TRAIN = 0x0444;
- CMD_REM_OOB_EXTENDED_DATA_REQ_REPLY = 0x0445; // Not currently used in system/bt
- // Link policy commands 0x0800
- CMD_HOLD_MODE = 0x0801;
- CMD_SNIFF_MODE = 0x0803;
- CMD_EXIT_SNIFF_MODE = 0x0804;
- CMD_PARK_MODE = 0x0805;
- CMD_EXIT_PARK_MODE = 0x0806;
- CMD_QOS_SETUP = 0x0807;
- CMD_ROLE_DISCOVERY = 0x0809;
- CMD_SWITCH_ROLE = 0x080B;
- CMD_READ_POLICY_SETTINGS = 0x080C;
- CMD_WRITE_POLICY_SETTINGS = 0x080D;
- CMD_READ_DEF_POLICY_SETTINGS = 0x080E;
- CMD_WRITE_DEF_POLICY_SETTINGS = 0x080F;
- CMD_FLOW_SPECIFICATION = 0x0810;
- CMD_SNIFF_SUB_RATE = 0x0811;
- // Host controller baseband commands 0x0C00
- CMD_SET_EVENT_MASK = 0x0C01;
- CMD_RESET = 0x0C03;
- CMD_SET_EVENT_FILTER = 0x0C05;
- CMD_FLUSH = 0x0C08;
- CMD_READ_PIN_TYPE = 0x0C09;
- CMD_WRITE_PIN_TYPE = 0x0C0A;
- CMD_CREATE_NEW_UNIT_KEY = 0x0C0B;
- CMD_GET_MWS_TRANS_LAYER_CFG = 0x0C0C; // Deprecated (not used in spec)
- CMD_READ_STORED_LINK_KEY = 0x0C0D;
- CMD_WRITE_STORED_LINK_KEY = 0x0C11;
- CMD_DELETE_STORED_LINK_KEY = 0x0C12;
- CMD_CHANGE_LOCAL_NAME = 0x0C13;
- CMD_READ_LOCAL_NAME = 0x0C14;
- CMD_READ_CONN_ACCEPT_TOUT = 0x0C15;
- CMD_WRITE_CONN_ACCEPT_TOUT = 0x0C16;
- CMD_READ_PAGE_TOUT = 0x0C17;
- CMD_WRITE_PAGE_TOUT = 0x0C18;
- CMD_READ_SCAN_ENABLE = 0x0C19;
- CMD_WRITE_SCAN_ENABLE = 0x0C1A;
- CMD_READ_PAGESCAN_CFG = 0x0C1B;
- CMD_WRITE_PAGESCAN_CFG = 0x0C1C;
- CMD_READ_INQUIRYSCAN_CFG = 0x0C1D;
- CMD_WRITE_INQUIRYSCAN_CFG = 0x0C1E;
- CMD_READ_AUTHENTICATION_ENABLE = 0x0C1F;
- CMD_WRITE_AUTHENTICATION_ENABLE = 0x0C20;
- CMD_READ_ENCRYPTION_MODE = 0x0C21; // Deprecated
- CMD_WRITE_ENCRYPTION_MODE = 0x0C22; // Deprecated
- CMD_READ_CLASS_OF_DEVICE = 0x0C23;
- CMD_WRITE_CLASS_OF_DEVICE = 0x0C24;
- CMD_READ_VOICE_SETTINGS = 0x0C25;
- CMD_WRITE_VOICE_SETTINGS = 0x0C26;
- CMD_READ_AUTOMATIC_FLUSH_TIMEOUT = 0x0C27;
- CMD_WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x0C28;
- CMD_READ_NUM_BCAST_REXMITS = 0x0C29;
- CMD_WRITE_NUM_BCAST_REXMITS = 0x0C2A;
- CMD_READ_HOLD_MODE_ACTIVITY = 0x0C2B;
- CMD_WRITE_HOLD_MODE_ACTIVITY = 0x0C2C;
- CMD_READ_TRANSMIT_POWER_LEVEL = 0x0C2D;
- CMD_READ_SCO_FLOW_CTRL_ENABLE = 0x0C2E;
- CMD_WRITE_SCO_FLOW_CTRL_ENABLE = 0x0C2F;
- CMD_SET_HC_TO_HOST_FLOW_CTRL = 0x0C31;
- CMD_HOST_BUFFER_SIZE = 0x0C33;
- CMD_HOST_NUM_PACKETS_DONE = 0x0C35;
- CMD_READ_LINK_SUPER_TOUT = 0x0C36;
- CMD_WRITE_LINK_SUPER_TOUT = 0x0C37;
- CMD_READ_NUM_SUPPORTED_IAC = 0x0C38;
- CMD_READ_CURRENT_IAC_LAP = 0x0C39;
- CMD_WRITE_CURRENT_IAC_LAP = 0x0C3A;
- CMD_READ_PAGESCAN_PERIOD_MODE = 0x0C3B; // Deprecated
- CMD_WRITE_PAGESCAN_PERIOD_MODE = 0x0C3C; // Deprecated
- CMD_READ_PAGESCAN_MODE = 0x0C3D; // Deprecated
- CMD_WRITE_PAGESCAN_MODE = 0x0C3E; // Deprecated
- CMD_SET_AFH_CHANNELS = 0x0C3F;
- CMD_READ_INQSCAN_TYPE = 0x0C42;
- CMD_WRITE_INQSCAN_TYPE = 0x0C43;
- CMD_READ_INQUIRY_MODE = 0x0C44;
- CMD_WRITE_INQUIRY_MODE = 0x0C45;
- CMD_READ_PAGESCAN_TYPE = 0x0C46;
- CMD_WRITE_PAGESCAN_TYPE = 0x0C47;
- CMD_READ_AFH_ASSESSMENT_MODE = 0x0C48;
- CMD_WRITE_AFH_ASSESSMENT_MODE = 0x0C49;
- CMD_READ_EXT_INQ_RESPONSE = 0x0C51;
- CMD_WRITE_EXT_INQ_RESPONSE = 0x0C52;
- CMD_REFRESH_ENCRYPTION_KEY = 0x0C53;
- CMD_READ_SIMPLE_PAIRING_MODE = 0x0C55;
- CMD_WRITE_SIMPLE_PAIRING_MODE = 0x0C56;
- CMD_READ_LOCAL_OOB_DATA = 0x0C57;
- CMD_READ_INQ_TX_POWER_LEVEL = 0x0C58;
- CMD_WRITE_INQ_TX_POWER_LEVEL = 0x0C59;
- CMD_READ_ERRONEOUS_DATA_RPT = 0x0C5A;
- CMD_WRITE_ERRONEOUS_DATA_RPT = 0x0C5B;
- CMD_ENHANCED_FLUSH = 0x0C5F;
- CMD_SEND_KEYPRESS_NOTIF = 0x0C60;
- CMD_READ_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C61;
- CMD_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C62;
- CMD_SET_EVENT_MASK_PAGE_2 = 0x0C63;
- CMD_READ_LOCATION_DATA = 0x0C64;
- CMD_WRITE_LOCATION_DATA = 0x0C65;
- CMD_READ_FLOW_CONTROL_MODE = 0x0C66;
- CMD_WRITE_FLOW_CONTROL_MODE = 0x0C67;
- CMD_READ_ENHANCED_TX_PWR_LEVEL = 0x0C68; // Not currently used in system/bt
- CMD_READ_BE_FLUSH_TOUT = 0x0C69;
- CMD_WRITE_BE_FLUSH_TOUT = 0x0C6A;
- CMD_SHORT_RANGE_MODE = 0x0C6B;
- CMD_READ_BLE_HOST_SUPPORT = 0x0C6C;
- CMD_WRITE_BLE_HOST_SUPPORT = 0x0C6D;
- CMD_SET_MWS_CHANNEL_PARAMETERS = 0x0C6E;
- CMD_SET_EXTERNAL_FRAME_CONFIGURATION = 0x0C6F;
- CMD_SET_MWS_SIGNALING = 0x0C70;
- CMD_SET_MWS_TRANSPORT_LAYER = 0x0C71;
- CMD_SET_MWS_SCAN_FREQUENCY_TABLE = 0x0C72;
- CMD_SET_MWS_PATTERN_CONFIGURATION = 0x0C73;
- CMD_SET_RESERVED_LT_ADDR = 0x0C74;
- CMD_DELETE_RESERVED_LT_ADDR = 0x0C75;
- CMD_WRITE_CLB_DATA = 0x0C76;
- CMD_READ_SYNC_TRAIN_PARAM = 0x0C77;
- CMD_WRITE_SYNC_TRAIN_PARAM = 0x0C78;
- CMD_READ_SECURE_CONNS_SUPPORT = 0x0C79;
- CMD_WRITE_SECURE_CONNS_SUPPORT = 0x0C7A;
- CMD_READ_AUTHED_PAYLOAD_TIMEOUT = 0x0C7B; // Not currently used in system/bt
- CMD_WRITE_AUTHED_PAYLOAD_TIMEOUT = 0x0C7C; // Not currently used in system/bt
- CMD_READ_LOCAL_OOB_EXTENDED_DATA = 0x0C7D; // Not currently used in system/bt
- CMD_READ_EXTENDED_PAGE_TIMEOUT = 0x0C7E; // Not currently used in system/bt
- CMD_WRITE_EXTENDED_PAGE_TIMEOUT = 0x0C7F; // Not currently used in system/bt
- CMD_READ_EXTENDED_INQUIRY_LENGTH = 0x0C80; // Not currently used in system/bt
- CMD_WRITE_EXTENDED_INQUIRY_LENGTH = 0x0C81; // Not currently used in system/bt
- // Informational parameter commands 0x1000
- CMD_READ_LOCAL_VERSION_INFO = 0x1001;
- CMD_READ_LOCAL_SUPPORTED_CMDS = 0x1002;
- CMD_READ_LOCAL_FEATURES = 0x1003;
- CMD_READ_LOCAL_EXT_FEATURES = 0x1004;
- CMD_READ_BUFFER_SIZE = 0x1005;
- CMD_READ_COUNTRY_CODE = 0x1007; // Deprecated
- CMD_READ_BD_ADDR = 0x1009;
- CMD_READ_DATA_BLOCK_SIZE = 0x100A;
- CMD_READ_LOCAL_SUPPORTED_CODECS = 0x100B;
- // Status parameter commands 0x1400
- CMD_READ_FAILED_CONTACT_COUNTER = 0x1401;
- CMD_RESET_FAILED_CONTACT_COUNTER = 0x1402;
- CMD_GET_LINK_QUALITY = 0x1403;
- CMD_READ_RSSI = 0x1405;
- CMD_READ_AFH_CH_MAP = 0x1406;
- CMD_READ_CLOCK = 0x1407;
- CMD_READ_ENCR_KEY_SIZE = 0x1408;
- CMD_READ_LOCAL_AMP_INFO = 0x1409;
- CMD_READ_LOCAL_AMP_ASSOC = 0x140A;
- CMD_WRITE_REMOTE_AMP_ASSOC = 0x140B;
- CMD_GET_MWS_TRANSPORT_CFG = 0x140C; // Not currently used in system/bt
- CMD_SET_TRIGGERED_CLK_CAPTURE = 0x140D; // Not currently used in system/bt
- // Testing commands 0x1800
- CMD_READ_LOOPBACK_MODE = 0x1801;
- CMD_WRITE_LOOPBACK_MODE = 0x1802;
- CMD_ENABLE_DEV_UNDER_TEST_MODE = 0x1803;
- CMD_WRITE_SIMP_PAIR_DEBUG_MODE = 0x1804;
- CMD_ENABLE_AMP_RCVR_REPORTS = 0x1807;
- CMD_AMP_TEST_END = 0x1808;
- CMD_AMP_TEST = 0x1809;
- CMD_WRITE_SECURE_CONN_TEST_MODE = 0x180A; // Not currently used in system/bt
- // BLE commands 0x2000
- CMD_BLE_SET_EVENT_MASK = 0x2001;
- CMD_BLE_READ_BUFFER_SIZE = 0x2002;
- CMD_BLE_READ_LOCAL_SPT_FEAT = 0x2003;
- CMD_BLE_WRITE_LOCAL_SPT_FEAT = 0x2004;
- CMD_BLE_WRITE_RANDOM_ADDR = 0x2005;
- CMD_BLE_WRITE_ADV_PARAMS = 0x2006;
- CMD_BLE_READ_ADV_CHNL_TX_POWER = 0x2007;
- CMD_BLE_WRITE_ADV_DATA = 0x2008;
- CMD_BLE_WRITE_SCAN_RSP_DATA = 0x2009;
- CMD_BLE_WRITE_ADV_ENABLE = 0x200A;
- CMD_BLE_WRITE_SCAN_PARAMS = 0x200B;
- CMD_BLE_WRITE_SCAN_ENABLE = 0x200C;
- CMD_BLE_CREATE_LL_CONN = 0x200D;
- CMD_BLE_CREATE_CONN_CANCEL = 0x200E;
- CMD_BLE_READ_WHITE_LIST_SIZE = 0x200F;
- CMD_BLE_CLEAR_WHITE_LIST = 0x2010;
- CMD_BLE_ADD_WHITE_LIST = 0x2011;
- CMD_BLE_REMOVE_WHITE_LIST = 0x2012;
- CMD_BLE_UPD_LL_CONN_PARAMS = 0x2013;
- CMD_BLE_SET_HOST_CHNL_CLASS = 0x2014;
- CMD_BLE_READ_CHNL_MAP = 0x2015;
- CMD_BLE_READ_REMOTE_FEAT = 0x2016;
- CMD_BLE_ENCRYPT = 0x2017;
- CMD_BLE_RAND = 0x2018;
- CMD_BLE_START_ENC = 0x2019;
- CMD_BLE_LTK_REQ_REPLY = 0x201A;
- CMD_BLE_LTK_REQ_NEG_REPLY = 0x201B;
- CMD_BLE_READ_SUPPORTED_STATES = 0x201C;
- CMD_BLE_RECEIVER_TEST = 0x201D;
- CMD_BLE_TRANSMITTER_TEST = 0x201E;
- CMD_BLE_TEST_END = 0x201F;
- CMD_BLE_RC_PARAM_REQ_REPLY = 0x2020;
- CMD_BLE_RC_PARAM_REQ_NEG_REPLY = 0x2021;
- CMD_BLE_SET_DATA_LENGTH = 0x2022;
- CMD_BLE_READ_DEFAULT_DATA_LENGTH = 0x2023;
- CMD_BLE_WRITE_DEFAULT_DATA_LENGTH = 0x2024;
- CMD_BLE_GENERATE_DHKEY = 0x2026; // Not currently used in system/bt
- CMD_BLE_ADD_DEV_RESOLVING_LIST = 0x2027;
- CMD_BLE_RM_DEV_RESOLVING_LIST = 0x2028;
- CMD_BLE_CLEAR_RESOLVING_LIST = 0x2029;
- CMD_BLE_READ_RESOLVING_LIST_SIZE = 0x202A;
- CMD_BLE_READ_RESOLVABLE_ADDR_PEER = 0x202B;
- CMD_BLE_READ_RESOLVABLE_ADDR_LOCAL = 0x202C;
- CMD_BLE_SET_ADDR_RESOLUTION_ENABLE = 0x202D;
- CMD_BLE_SET_RAND_PRIV_ADDR_TIMOUT = 0x202E;
- CMD_BLE_READ_MAXIMUM_DATA_LENGTH = 0x202F;
- CMD_BLE_READ_PHY = 0x2030;
- CMD_BLE_SET_DEFAULT_PHY = 0x2031;
- CMD_BLE_SET_PHY = 0x2032;
- CMD_BLE_ENH_RECEIVER_TEST = 0x2033;
- CMD_BLE_ENH_TRANSMITTER_TEST = 0x2034;
- CMD_BLE_SET_EXT_ADVERTISING_RANDOM_ADDRESS = 0x2035;
- CMD_BLE_SET_EXT_ADVERTISING_PARAM = 0x2036;
- CMD_BLE_SET_EXT_ADVERTISING_DATA = 0x2037;
- CMD_BLE_SET_EXT_ADVERTISING_SCAN_RESP = 0x2038;
- CMD_BLE_SET_EXT_ADVERTISING_ENABLE = 0x2039;
- CMD_BLE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 0x203A;
- CMD_BLE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 0x203B;
- CMD_BLE_REMOVE_ADVERTISING_SET = 0x203C;
- CMD_BLE_CLEAR_ADVERTISING_SETS = 0x203D;
- CMD_BLE_SET_PERIODIC_ADVERTISING_PARAM = 0x203E;
- CMD_BLE_SET_PERIODIC_ADVERTISING_DATA = 0x203F;
- CMD_BLE_SET_PERIODIC_ADVERTISING_ENABLE = 0x2040;
- CMD_BLE_SET_EXTENDED_SCAN_PARAMETERS = 0x2041;
- CMD_BLE_SET_EXTENDED_SCAN_ENABLE = 0x2042;
- CMD_BLE_EXTENDED_CREATE_CONNECTION = 0x2043;
- CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC = 0x2044;
- CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 0x2045;
- CMD_BLE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 0x2046;
- CMD_BLE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = 0x2047;
- CMD_BLE_RM_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = 0x2048;
- CMD_BLE_CLEAR_PERIODIC_ADVERTISING_LIST = 0x2049;
- CMD_BLE_READ_PERIODIC_ADVERTISING_LIST_SIZE = 0x204A;
- CMD_BLE_READ_TRANSMIT_POWER = 0x204B;
- CMD_BLE_READ_RF_COMPENS_POWER = 0x204C;
- CMD_BLE_WRITE_RF_COMPENS_POWER = 0x204D;
- CMD_BLE_SET_PRIVACY_MODE = 0x204E;
- // Vendor specific commands 0xFC00 and above
- // Android vendor specific commands defined in
- // https://source.android.com/devices/bluetooth/hci_requirements#vendor-specific-capabilities
- CMD_BLE_VENDOR_CAP = 0xFD53;
- CMD_BLE_MULTI_ADV = 0xFD54;
- CMD_BLE_BATCH_SCAN = 0xFD56;
- CMD_BLE_ADV_FILTER = 0xFD57;
- CMD_BLE_TRACK_ADV = 0xFD58;
- CMD_BLE_ENERGY_INFO = 0xFD59;
- CMD_BLE_EXTENDED_SCAN_PARAMS = 0xFD5A;
- CMD_CONTROLLER_DEBUG_INFO = 0xFD5B;
- CMD_CONTROLLER_A2DP_OPCODE = 0xFD5D;
- CMD_BRCM_SET_ACL_PRIORITY = 0xFC57;
- // Other vendor specific commands below here
-}
-
-// HCI event codes from the Bluetooth 5.0 specification Vol 2, Part 7, Section 7
-// Original definition: system/bt/stack/include/hcidefs.h
-enum EventEnum {
- // Event is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- EVT_UNKNOWN = 0xFFF;
- EVT_INQUIRY_COMP = 0x01;
- EVT_INQUIRY_RESULT = 0x02;
- EVT_CONNECTION_COMP = 0x03;
- EVT_CONNECTION_REQUEST = 0x04;
- EVT_DISCONNECTION_COMP = 0x05;
- EVT_AUTHENTICATION_COMP = 0x06;
- EVT_RMT_NAME_REQUEST_COMP = 0x07;
- EVT_ENCRYPTION_CHANGE = 0x08;
- EVT_CHANGE_CONN_LINK_KEY = 0x09;
- EVT_MASTER_LINK_KEY_COMP = 0x0A;
- EVT_READ_RMT_FEATURES_COMP = 0x0B;
- EVT_READ_RMT_VERSION_COMP = 0x0C;
- EVT_QOS_SETUP_COMP = 0x0D;
- EVT_COMMAND_COMPLETE = 0x0E;
- EVT_COMMAND_STATUS = 0x0F;
- EVT_HARDWARE_ERROR = 0x10;
- EVT_FLUSH_OCCURRED = 0x11;
- EVT_ROLE_CHANGE = 0x12;
- EVT_NUM_COMPL_DATA_PKTS = 0x13;
- EVT_MODE_CHANGE = 0x14;
- EVT_RETURN_LINK_KEYS = 0x15;
- EVT_PIN_CODE_REQUEST = 0x16;
- EVT_LINK_KEY_REQUEST = 0x17;
- EVT_LINK_KEY_NOTIFICATION = 0x18;
- EVT_LOOPBACK_COMMAND = 0x19;
- EVT_DATA_BUF_OVERFLOW = 0x1A;
- EVT_MAX_SLOTS_CHANGED = 0x1B;
- EVT_READ_CLOCK_OFF_COMP = 0x1C;
- EVT_CONN_PKT_TYPE_CHANGE = 0x1D;
- EVT_QOS_VIOLATION = 0x1E;
- EVT_PAGE_SCAN_MODE_CHANGE = 0x1F; // Deprecated
- EVT_PAGE_SCAN_REP_MODE_CHNG = 0x20;
- EVT_FLOW_SPECIFICATION_COMP = 0x21;
- EVT_INQUIRY_RSSI_RESULT = 0x22;
- EVT_READ_RMT_EXT_FEATURES_COMP = 0x23;
- EVT_ESCO_CONNECTION_COMP = 0x2C;
- EVT_ESCO_CONNECTION_CHANGED = 0x2D;
- EVT_SNIFF_SUB_RATE = 0x2E;
- EVT_EXTENDED_INQUIRY_RESULT = 0x2F;
- EVT_ENCRYPTION_KEY_REFRESH_COMP = 0x30;
- EVT_IO_CAPABILITY_REQUEST = 0x31;
- EVT_IO_CAPABILITY_RESPONSE = 0x32;
- EVT_USER_CONFIRMATION_REQUEST = 0x33;
- EVT_USER_PASSKEY_REQUEST = 0x34;
- EVT_REMOTE_OOB_DATA_REQUEST = 0x35;
- EVT_SIMPLE_PAIRING_COMPLETE = 0x36;
- EVT_LINK_SUPER_TOUT_CHANGED = 0x38;
- EVT_ENHANCED_FLUSH_COMPLETE = 0x39;
- EVT_USER_PASSKEY_NOTIFY = 0x3B;
- EVT_KEYPRESS_NOTIFY = 0x3C;
- EVT_RMT_HOST_SUP_FEAT_NOTIFY = 0x3D;
- EVT_BLE_META = 0x3E;
- EVT_PHYSICAL_LINK_COMP = 0x40;
- EVT_CHANNEL_SELECTED = 0x41;
- EVT_DISC_PHYSICAL_LINK_COMP = 0x42;
- EVT_PHY_LINK_LOSS_EARLY_WARNING = 0x43;
- EVT_PHY_LINK_RECOVERY = 0x44;
- EVT_LOGICAL_LINK_COMP = 0x45;
- EVT_DISC_LOGICAL_LINK_COMP = 0x46;
- EVT_FLOW_SPEC_MODIFY_COMP = 0x47;
- EVT_NUM_COMPL_DATA_BLOCKS = 0x48;
- EVT_AMP_TEST_START = 0x49; // Not currently used in system/bt
- EVT_AMP_TEST_END = 0x4A; // Not currently used in system/bt
- EVT_AMP_RECEIVER_RPT = 0x4B; // Not currently used in system/bt
- EVT_SHORT_RANGE_MODE_COMPLETE = 0x4C;
- EVT_AMP_STATUS_CHANGE = 0x4D;
- EVT_SET_TRIGGERED_CLOCK_CAPTURE = 0x4E;
- EVT_SYNC_TRAIN_CMPL = 0x4F; // Not currently used in system/bt
- EVT_SYNC_TRAIN_RCVD = 0x50; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_RCVD = 0x51; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_TIMEOUT = 0x52; // Not currently used in system/bt
- EVT_TRUNCATED_PAGE_CMPL = 0x53; // Not currently used in system/bt
- EVT_SLAVE_PAGE_RES_TIMEOUT = 0x54; // Not currently used in system/bt
- EVT_CONNLESS_SLAVE_BROADCAST_CHNL_MAP_CHANGE = 0x55; // Not currently used in system/bt
- EVT_INQUIRY_RES_NOTIFICATION = 0x56; // Not currently used in system/bt
- EVT_AUTHED_PAYLOAD_TIMEOUT = 0x57; // Not currently used in system/bt
- EVT_SAM_STATUS_CHANGE = 0x58; // Not currently used in system/bt
-}
-
-// Bluetooth low energy related meta event codes
-// from the Bluetooth 5.0 specification Vol 2, Part E, Section 7.7.65
-// Original definition: system/bt/stack/include/hcidefs.h
-enum BleMetaEventEnum {
- // BLE meta event code is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- BLE_EVT_UNKNOWN = 0xFFF;
- BLE_EVT_CONN_COMPLETE_EVT = 0x01;
- BLE_EVT_ADV_PKT_RPT_EVT = 0x02;
- BLE_EVT_LL_CONN_PARAM_UPD_EVT = 0x03;
- BLE_EVT_READ_REMOTE_FEAT_CMPL_EVT = 0x04;
- BLE_EVT_LTK_REQ_EVT = 0x05;
- BLE_EVT_RC_PARAM_REQ_EVT = 0x06;
- BLE_EVT_DATA_LENGTH_CHANGE_EVT = 0x07;
- BLE_EVT_READ_LOCAL_P256_PUB_KEY = 0x08; // Not currently used in system/bt
- BLE_EVT_GEN_DHKEY_CMPL = 0x09; // Not currently used in system/bt
- BLE_EVT_ENHANCED_CONN_COMPLETE_EVT = 0x0a;
- BLE_EVT_DIRECT_ADV_EVT = 0x0b;
- BLE_EVT_PHY_UPDATE_COMPLETE_EVT = 0x0c;
- BLE_EVT_EXTENDED_ADVERTISING_REPORT_EVT = 0x0D;
- BLE_EVT_PERIODIC_ADV_SYNC_EST_EVT = 0x0E;
- BLE_EVT_PERIODIC_ADV_REPORT_EVT = 0x0F;
- BLE_EVT_PERIODIC_ADV_SYNC_LOST_EVT = 0x10;
- BLE_EVT_SCAN_TIMEOUT_EVT = 0x11;
- BLE_EVT_ADVERTISING_SET_TERMINATED_EVT = 0x12;
- BLE_EVT_SCAN_REQ_RX_EVT = 0x13;
- BLE_EVT_CHNL_SELECTION_ALGORITHM = 0x14; // Not currently used in system/bt
-}
-
-// HCI status code from the Bluetooth 5.0 specification Vol 2, Part D.
-// Original definition: system/bt/stack/include/hcidefs.h
-enum StatusEnum {
- // Status is at most 1 byte (0xFF), thus 0xFFF must not be a valid value
- STATUS_UNKNOWN = 0xFFF;
- STATUS_SUCCESS = 0x00;
- STATUS_ILLEGAL_COMMAND = 0x01;
- STATUS_NO_CONNECTION = 0x02;
- STATUS_HW_FAILURE = 0x03;
- STATUS_PAGE_TIMEOUT = 0x04;
- STATUS_AUTH_FAILURE = 0x05;
- STATUS_KEY_MISSING = 0x06;
- STATUS_MEMORY_FULL = 0x07;
- STATUS_CONNECTION_TOUT = 0x08;
- STATUS_MAX_NUM_OF_CONNECTIONS = 0x09;
- STATUS_MAX_NUM_OF_SCOS = 0x0A;
- STATUS_CONNECTION_EXISTS = 0x0B;
- STATUS_COMMAND_DISALLOWED = 0x0C;
- STATUS_HOST_REJECT_RESOURCES = 0x0D;
- STATUS_HOST_REJECT_SECURITY = 0x0E;
- STATUS_HOST_REJECT_DEVICE = 0x0F;
- STATUS_HOST_TIMEOUT = 0x10;
- STATUS_UNSUPPORTED_VALUE = 0x11;
- STATUS_ILLEGAL_PARAMETER_FMT = 0x12;
- STATUS_PEER_USER = 0x13;
- STATUS_PEER_LOW_RESOURCES = 0x14;
- STATUS_PEER_POWER_OFF = 0x15;
- STATUS_CONN_CAUSE_LOCAL_HOST = 0x16;
- STATUS_REPEATED_ATTEMPTS = 0x17;
- STATUS_PAIRING_NOT_ALLOWED = 0x18;
- STATUS_UNKNOWN_LMP_PDU = 0x19;
- STATUS_UNSUPPORTED_REM_FEATURE = 0x1A;
- STATUS_SCO_OFFSET_REJECTED = 0x1B;
- STATUS_SCO_INTERVAL_REJECTED = 0x1C;
- STATUS_SCO_AIR_MODE = 0x1D;
- STATUS_INVALID_LMP_PARAM = 0x1E;
- STATUS_UNSPECIFIED = 0x1F;
- STATUS_UNSUPPORTED_LMP_FEATURE = 0x20;
- STATUS_ROLE_CHANGE_NOT_ALLOWED = 0x21;
- STATUS_LMP_RESPONSE_TIMEOUT = 0x22;
- STATUS_LMP_STATUS_TRANS_COLLISION = 0x23;
- STATUS_LMP_PDU_NOT_ALLOWED = 0x24;
- STATUS_ENCRY_MODE_NOT_ACCEPTABLE = 0x25;
- STATUS_UNIT_KEY_USED = 0x26;
- STATUS_QOS_NOT_SUPPORTED = 0x27;
- STATUS_INSTANT_PASSED = 0x28;
- STATUS_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29;
- STATUS_DIFF_TRANSACTION_COLLISION = 0x2A;
- STATUS_UNDEFINED_0x2B = 0x2B; // Not used
- STATUS_QOS_UNACCEPTABLE_PARAM = 0x2C;
- STATUS_QOS_REJECTED = 0x2D;
- STATUS_CHAN_CLASSIF_NOT_SUPPORTED = 0x2E;
- STATUS_INSUFFCIENT_SECURITY = 0x2F;
- STATUS_PARAM_OUT_OF_RANGE = 0x30;
- STATUS_UNDEFINED_0x31 = 0x31; // Not used
- STATUS_ROLE_SWITCH_PENDING = 0x32;
- STATUS_UNDEFINED_0x33 = 0x33;
- STATUS_RESERVED_SLOT_VIOLATION = 0x34;
- STATUS_ROLE_SWITCH_FAILED = 0x35;
- STATUS_INQ_RSP_DATA_TOO_LARGE = 0x36;
- STATUS_SIMPLE_PAIRING_NOT_SUPPORTED = 0x37;
- STATUS_HOST_BUSY_PAIRING = 0x38;
- STATUS_REJ_NO_SUITABLE_CHANNEL = 0x39;
- STATUS_CONTROLLER_BUSY = 0x3A;
- STATUS_UNACCEPT_CONN_INTERVAL = 0x3B;
- STATUS_ADVERTISING_TIMEOUT = 0x3C;
- STATUS_CONN_TOUT_DUE_TO_MIC_FAILURE = 0x3D;
- STATUS_CONN_FAILED_ESTABLISHMENT = 0x3E;
- STATUS_MAC_CONNECTION_FAILED = 0x3F;
- STATUS_LT_ADDR_ALREADY_IN_USE = 0x40;
- STATUS_LT_ADDR_NOT_ALLOCATED = 0x41;
- STATUS_CLB_NOT_ENABLED = 0x42;
- STATUS_CLB_DATA_TOO_BIG = 0x43;
- STATUS_OPERATION_CANCELED_BY_HOST = 0x44; // Not currently used in system/bt
-}
-
-enum BqrIdEnum {
- BQR_ID_UNKNOWN = 0x00;
- BQR_ID_MONITOR_MODE = 0x01;
- BQR_ID_APPROACH_LSTO = 0x02;
- BQR_ID_A2DP_AUDIO_CHOPPY = 0x03;
- BQR_ID_SCO_VOICE_CHOPPY = 0x04;
-}
-
-enum BqrPacketTypeEnum {
- BQR_PACKET_TYPE_UNKNOWN = 0x00;
- BQR_PACKET_TYPE_ID = 0x01;
- BQR_PACKET_TYPE_NULL = 0x02;
- BQR_PACKET_TYPE_POLL = 0x03;
- BQR_PACKET_TYPE_FHS = 0x04;
- BQR_PACKET_TYPE_HV1 = 0x05;
- BQR_PACKET_TYPE_HV2 = 0x06;
- BQR_PACKET_TYPE_HV3 = 0x07;
- BQR_PACKET_TYPE_DV = 0x08;
- BQR_PACKET_TYPE_EV3 = 0x09;
- BQR_PACKET_TYPE_EV4 = 0x0A;
- BQR_PACKET_TYPE_EV5 = 0x0B;
- BQR_PACKET_TYPE_2EV3 = 0x0C;
- BQR_PACKET_TYPE_2EV5 = 0x0D;
- BQR_PACKET_TYPE_3EV3 = 0x0E;
- BQR_PACKET_TYPE_3EV5 = 0x0F;
- BQR_PACKET_TYPE_DM1 = 0x10;
- BQR_PACKET_TYPE_DH1 = 0x11;
- BQR_PACKET_TYPE_DM3 = 0x12;
- BQR_PACKET_TYPE_DH3 = 0x13;
- BQR_PACKET_TYPE_DM5 = 0x14;
- BQR_PACKET_TYPE_DH5 = 0x15;
- BQR_PACKET_TYPE_AUX1 = 0x16;
- BQR_PACKET_TYPE_2DH1 = 0x17;
- BQR_PACKET_TYPE_2DH3 = 0x18;
- BQR_PACKET_TYPE_2DH5 = 0x19;
- BQR_PACKET_TYPE_3DH1 = 0x1A;
- BQR_PACKET_TYPE_3DH3 = 0x1B;
- BQR_PACKET_TYPE_3DH5 = 0x1C;
-}
diff --git a/core/proto/android/bluetooth/smp/enums.proto b/core/proto/android/bluetooth/smp/enums.proto
deleted file mode 100644
index c6747b78dc29..000000000000
--- a/core/proto/android/bluetooth/smp/enums.proto
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.bluetooth.smp;
-
-option java_outer_classname = "BluetoothSmpProtoEnums";
-option java_multiple_files = true;
-
-// SMP Pairing command codes
-enum CommandEnum {
- CMD_UNKNOWN = 0x00;
- CMD_PAIRING_REQUEST = 0x01;
- CMD_PAIRING_RESPONSE = 0x02;
- CMD_PAIRING_CONFIRM = 0x03;
- CMD_PAIRING_RANDOM = 0x04;
- CMD_PAIRING_FAILED = 0x05;
- CMD_ENCRYPTION_INFON = 0x06;
- CMD_MASTER_IDENTIFICATION = 0x07;
- CMD_IDENTITY_INFO = 0x08;
- CMD_IDENTITY_ADDR_INFO = 0x09;
- CMD_SIGNING_INFO = 0x0A;
- CMD_SECURITY_REQUEST = 0x0B;
- CMD_PAIRING_PUBLIC_KEY = 0x0C;
- CMD_PAIRING_DHKEY_CHECK = 0x0D;
- CMD_PAIRING_KEYPRESS_INFO = 0x0E;
-}
-
-enum PairingFailReasonEnum {
- PAIRING_FAIL_REASON_RESERVED = 0x00;
- PAIRING_FAIL_REASON_PASSKEY_ENTRY = 0x01;
- PAIRING_FAIL_REASON_OOB = 0x02;
- PAIRING_FAIL_REASON_AUTH_REQ = 0x03;
- PAIRING_FAIL_REASON_CONFIRM_VALUE = 0x04;
- PAIRING_FAIL_REASON_PAIR_NOT_SUPPORT = 0x05;
- PAIRING_FAIL_REASON_ENC_KEY_SIZE = 0x06;
- PAIRING_FAIL_REASON_INVALID_CMD = 0x07;
- PAIRING_FAIL_REASON_UNSPECIFIED = 0x08;
- PAIRING_FAIL_REASON_REPEATED_ATTEMPTS = 0x09;
- PAIRING_FAIL_REASON_INVALID_PARAMETERS = 0x0A;
- PAIRING_FAIL_REASON_DHKEY_CHK = 0x0B;
- PAIRING_FAIL_REASON_NUMERIC_COMPARISON = 0x0C;
- PAIRING_FAIL_REASON_CLASSIC_PAIRING_IN_PROGR = 0x0D;
- PAIRING_FAIL_REASON_XTRANS_DERIVE_NOT_ALLOW = 0x0E;
-} \ No newline at end of file
diff --git a/core/proto/android/debug/enums.proto b/core/proto/android/debug/enums.proto
deleted file mode 100644
index 6747bb7276b3..000000000000
--- a/core/proto/android/debug/enums.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.debug;
-
-option java_outer_classname = "AdbProtoEnums";
-option java_multiple_files = true;
-
-/**
- * adb connection state used to track adb connection changes in AdbDebuggingManager.java.
- */
-enum AdbConnectionStateEnum {
- UNKNOWN = 0;
-
- /**
- * The adb connection is waiting for approval from the user.
- */
- AWAITING_USER_APPROVAL = 1;
-
- /**
- * The user allowed the adb connection from the system.
- */
- USER_ALLOWED = 2;
-
- /**
- * The user denied the adb connection from the system.
- */
- USER_DENIED = 3;
-
- /**
- * The adb connection was automatically allowed without user interaction due to the system
- * being previously allowed by the user with the 'always allow' option selected, and the adb
- * grant has not yet expired.
- */
- AUTOMATICALLY_ALLOWED = 4;
-
- /**
- * An empty or invalid base64 encoded key was provided to the framework; the connection was
- * automatically denied.
- */
- DENIED_INVALID_KEY = 5;
-
- /**
- * vold decrypt has not yet occurred; the connection was automatically denied.
- */
- DENIED_VOLD_DECRYPT = 6;
-
- /**
- * The adb session has been disconnected.
- */
- DISCONNECTED = 7;
-}
-
diff --git a/core/proto/android/hardware/biometrics/enums.proto b/core/proto/android/hardware/biometrics/enums.proto
deleted file mode 100644
index f2e06383b5b1..000000000000
--- a/core/proto/android/hardware/biometrics/enums.proto
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.hardware.biometrics;
-
-option java_outer_classname = "BiometricsProtoEnums";
-option java_multiple_files = true;
-
-// Logging constants for <Biometric>Service and BiometricService
-
-enum ModalityEnum {
- MODALITY_UNKNOWN = 0;
- MODALITY_FINGERPRINT = 1; // 1 << 0
- MODALITY_IRIS = 2; // 1 << 1
- MODALITY_FACE = 4; // 1 << 2
-}
-
-enum ClientEnum {
- CLIENT_UNKNOWN = 0;
- CLIENT_KEYGUARD = 1;
- CLIENT_BIOMETRIC_PROMPT = 2;
- CLIENT_FINGERPRINT_MANAGER = 3; // Deprecated API before BiometricPrompt was introduced
-}
-
-enum ActionEnum {
- ACTION_UNKNOWN = 0;
- ACTION_ENROLL = 1;
- ACTION_AUTHENTICATE = 2;
- ACTION_ENUMERATE = 3;
- ACTION_REMOVE = 4;
-}
-
-enum IssueEnum {
- ISSUE_UNKNOWN = 0;
- // When a biometric HAL has crashed.
- ISSUE_HAL_DEATH = 1;
- // When Android Framework has a template that doesn't exist in the HAL. The framework
- // is expected to remove its template to stay in sync with the HAL.
- ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK = 2;
- // When the HAL has a template that doesn't exist in Android Framework. The framework
- // is expected to notify the HAL to remove this template to stay in sync with the framework.
- ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL = 3;
- // When the HAL has not sent ERROR_CANCELED within the specified timeout.
- ISSUE_CANCEL_TIMED_OUT = 4;
-} \ No newline at end of file
diff --git a/core/proto/android/hardware/sensor/assist/enums.proto b/core/proto/android/hardware/sensor/assist/enums.proto
deleted file mode 100644
index 012dcb2e937e..000000000000
--- a/core/proto/android/hardware/sensor/assist/enums.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.hardware.sensor.assist;
-
-option java_outer_classname = "AssistGestureProtoEnums";
-option java_multiple_files = true;
-
-enum AssistGestureStageEnum {
- ASSIST_GESTURE_STAGE_UNKNOWN = 0;
- ASSIST_GESTURE_STAGE_PROGRESS = 1;
- ASSIST_GESTURE_STAGE_PRIMED = 2;
- ASSIST_GESTURE_STAGE_DETECTED = 3;
-}
-
-enum AssistGestureFeedbackEnum {
- ASSIST_GESTURE_FEEDBACK_UNKNOWN = 0;
- ASSIST_GESTURE_FEEDBACK_NOT_USED = 1;
- ASSIST_GESTURE_FEEDBACK_USED = 2;
-} \ No newline at end of file
diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto
deleted file mode 100644
index be0cad18a24d..000000000000
--- a/core/proto/android/net/networkcapabilities.proto
+++ /dev/null
@@ -1,133 +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.
- */
-
-syntax = "proto2";
-
-package android.net;
-
-option java_multiple_files = true;
-
-import "frameworks/base/core/proto/android/privacy.proto";
-
-/**
- * An android.net.NetworkCapabilities object.
- */
-message NetworkCapabilitiesProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- enum Transport {
- // Indicates this network uses a Cellular transport.
- TRANSPORT_CELLULAR = 0;
- // Indicates this network uses a Wi-Fi transport.
- TRANSPORT_WIFI = 1;
- // Indicates this network uses a Bluetooth transport.
- TRANSPORT_BLUETOOTH = 2;
- // Indicates this network uses an Ethernet transport.
- TRANSPORT_ETHERNET = 3;
- // Indicates this network uses a VPN transport.
- TRANSPORT_VPN = 4;
- // Indicates this network uses a Wi-Fi Aware transport.
- TRANSPORT_WIFI_AWARE = 5;
- // Indicates this network uses a LoWPAN transport.
- TRANSPORT_LOWPAN = 6;
- }
- repeated Transport transports = 1;
-
- enum NetCapability {
- // Indicates this is a network that has the ability to reach the
- // carrier's MMSC for sending and receiving MMS messages.
- NET_CAPABILITY_MMS = 0;
- // Indicates this is a network that has the ability to reach the
- // carrier's SUPL server, used to retrieve GPS information.
- NET_CAPABILITY_SUPL = 1;
- // Indicates this is a network that has the ability to reach the
- // carrier's DUN or tethering gateway.
- NET_CAPABILITY_DUN = 2;
- // Indicates this is a network that has the ability to reach the
- // carrier's FOTA portal, used for over the air updates.
- NET_CAPABILITY_FOTA = 3;
- // Indicates this is a network that has the ability to reach the
- // carrier's IMS servers, used for network registration and signaling.
- NET_CAPABILITY_IMS = 4;
- // Indicates this is a network that has the ability to reach the
- // carrier's CBS servers, used for carrier specific services.
- NET_CAPABILITY_CBS = 5;
- // Indicates this is a network that has the ability to reach a Wi-Fi
- // direct peer.
- NET_CAPABILITY_WIFI_P2P = 6;
- // Indicates this is a network that has the ability to reach a carrier's
- // Initial Attach servers.
- NET_CAPABILITY_IA = 7;
- // Indicates this is a network that has the ability to reach a carrier's
- // RCS servers, used for Rich Communication Services.
- NET_CAPABILITY_RCS = 8;
- // Indicates this is a network that has the ability to reach a carrier's
- // XCAP servers, used for configuration and control.
- NET_CAPABILITY_XCAP = 9;
- // Indicates this is a network that has the ability to reach a carrier's
- // Emergency IMS servers or other services, used for network signaling
- // during emergency calls.
- NET_CAPABILITY_EIMS = 10;
- // Indicates that this network is unmetered.
- NET_CAPABILITY_NOT_METERED = 11;
- // Indicates that this network should be able to reach the internet.
- NET_CAPABILITY_INTERNET = 12;
- // Indicates that this network is available for general use. If this is
- // not set applications should not attempt to communicate on this
- // network. Note that this is simply informative and not enforcement -
- // enforcement is handled via other means. Set by default.
- NET_CAPABILITY_NOT_RESTRICTED = 13;
- // Indicates that the user has indicated implicit trust of this network.
- // This generally means it's a sim-selected carrier, a plugged in
- // ethernet, a paired BT device or a wifi the user asked to connect to.
- // Untrusted networks are probably limited to unknown wifi AP. Set by
- // default.
- NET_CAPABILITY_TRUSTED = 14;
- // Indicates that this network is not a VPN. This capability is set by
- // default and should be explicitly cleared for VPN networks.
- NET_CAPABILITY_NOT_VPN = 15;
- // Indicates that connectivity on this network was successfully
- // validated. For example, for a network with NET_CAPABILITY_INTERNET,
- // it means that Internet connectivity was successfully detected.
- NET_CAPABILITY_VALIDATED = 16;
- // Indicates that this network was found to have a captive portal in
- // place last time it was probed.
- NET_CAPABILITY_CAPTIVE_PORTAL = 17;
- // Indicates that this network is not roaming.
- NET_CAPABILITY_NOT_ROAMING = 18;
- // Indicates that this network is available for use by apps, and not a
- // network that is being kept up in the background to facilitate fast
- // network switching.
- NET_CAPABILITY_FOREGROUND = 19;
- }
- repeated NetCapability capabilities = 2;
-
- // Passive link bandwidth. This is a rough guide of the expected peak
- // bandwidth for the first hop on the given transport. It is not measured,
- // but may take into account link parameters (Radio technology, allocated
- // channels, etc).
- optional int32 link_up_bandwidth_kbps = 3;
- optional int32 link_down_bandwidth_kbps = 4;
-
- optional string network_specifier = 5 [ (.android.privacy).dest = DEST_EXPLICIT ];
-
- // True if this object specifies a signal strength.
- optional bool can_report_signal_strength = 6;
- // This is a signed integer, and higher values indicate better signal. The
- // exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
- // Only valid if can_report_signal_strength is true.
- optional sint32 signal_strength = 7;
-}
diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto
index b35a0203ff02..6794c8cd8acb 100644
--- a/core/proto/android/net/networkrequest.proto
+++ b/core/proto/android/net/networkrequest.proto
@@ -20,8 +20,8 @@ package android.net;
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/net/networkcapabilities.proto";
/**
* An android.net.NetworkRequest object.
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 892ebf70ca75..7d68a0df23d5 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -19,10 +19,10 @@ option java_multiple_files = true;
package android.os;
-import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/os/powermanager.proto";
-import "frameworks/base/core/proto/android/telephony/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/job/enums.proto";
+import "frameworks/proto_logging/stats/enums/telephony/enums.proto";
message BatteryStatsProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/enums.proto b/core/proto/android/os/enums.proto
deleted file mode 100644
index 566861b6e836..000000000000
--- a/core/proto/android/os/enums.proto
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.os;
-
-option java_outer_classname = "OsProtoEnums";
-option java_multiple_files = true;
-
-// These constants are defined in hardware/interfaces/health/1.0/types.hal
-// They are primarily used by android/os/BatteryManager.java.
-enum BatteryHealthEnum {
- BATTERY_HEALTH_INVALID = 0;
- BATTERY_HEALTH_UNKNOWN = 1;
- BATTERY_HEALTH_GOOD = 2;
- BATTERY_HEALTH_OVERHEAT = 3;
- BATTERY_HEALTH_DEAD = 4;
- BATTERY_HEALTH_OVER_VOLTAGE = 5;
- BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
- BATTERY_HEALTH_COLD = 7;
-}
-
-// Plug states, primarily used by android/os/BatteryManager.java.
-enum BatteryPluggedStateEnum {
- // Note that NONE is not in BatteryManager.java's constants.
- BATTERY_PLUGGED_NONE = 0;
- // Power source is an AC charger.
- BATTERY_PLUGGED_AC = 1;
- // Power source is a USB port.
- BATTERY_PLUGGED_USB = 2;
- // Power source is wireless.
- BATTERY_PLUGGED_WIRELESS = 4;
-}
-
-// These constants are defined in hardware/interfaces/health/1.0/types.hal
-// They are primarily used by android/os/BatteryManager.java.
-enum BatteryStatusEnum {
- BATTERY_STATUS_INVALID = 0;
- BATTERY_STATUS_UNKNOWN = 1;
- BATTERY_STATUS_CHARGING = 2;
- BATTERY_STATUS_DISCHARGING = 3;
- BATTERY_STATUS_NOT_CHARGING = 4;
- BATTERY_STATUS_FULL = 5;
-}
-
-// These constants are defined in hardware/interfaces/thermal/1.0/types.hal
-// and in hardware/interfaces/thermal/2.0/types.hal
-// They are primarily used by android/os/HardwarePropertiesManager.java.
-// Any change to the types in the thermal hal should be made here as well.
-enum TemperatureTypeEnum {
- TEMPERATURE_TYPE_UNKNOWN = -1;
- TEMPERATURE_TYPE_CPU = 0;
- TEMPERATURE_TYPE_GPU = 1;
- TEMPERATURE_TYPE_BATTERY = 2;
- TEMPERATURE_TYPE_SKIN = 3;
- TEMPERATURE_TYPE_USB_PORT = 4;
- TEMPERATURE_TYPE_POWER_AMPLIFIER = 5;
-
- // Battery Charge Limit - virtual thermal sensors.
- TEMPERATURE_TYPE_BCL_VOLTAGE = 6;
- TEMPERATURE_TYPE_BCL_CURRENT = 7;
- TEMPERATURE_TYPE_BCL_PERCENTAGE = 8;
-
- // Neural Processing Unit.
- TEMPERATURE_TYPE_NPU = 9;
-}
-
-// Device throttling severity
-// These constants are defined in hardware/interfaces/thermal/2.0/types.hal.
-// Any change to the types in the thermal hal should be made here as well.
-enum ThrottlingSeverityEnum {
- // Not under throttling.
- NONE = 0;
- // Light throttling where UX is not impacted.
- LIGHT = 1;
- // Moderate throttling where UX is not largely impacted.
- MODERATE = 2;
- // Severe throttling where UX is largely impacted.
- // Similar to 1.0 throttlingThreshold.
- SEVERE = 3;
- // Platform has done everything to reduce power.
- CRITICAL = 4;
- // Key components in platform are shutting down due to thermal condition.
- // Device functionalities will be limited.
- EMERGENCY = 5;
- // Need shutdown immediately.
- SHUTDOWN = 6;
-};
-
-// Device cooling device types.
-// These constants are defined in hardware/interfaces/thermal/2.0/types.hal.
-// Any change to the types in the thermal hal should be made here as well.
-enum CoolingTypeEnum {
- FAN = 0;
- BATTERY = 1;
- CPU = 2;
- GPU = 3;
- MODEM = 4;
- NPU = 5;
- COMPONENT = 6;
-};
-
-// Wakelock types, primarily used by android/os/PowerManager.java.
-enum WakeLockLevelEnum {
- // NOTE: Wake lock levels were previously defined as a bit field, except
- // that only a few combinations were actually supported so the bit field
- // was removed. This explains why the numbering scheme is so odd. If
- // adding a new wake lock level, any unused value can be used.
-
- // Ensures that the CPU is running; the screen and keyboard backlight
- // will be allowed to go off.
- PARTIAL_WAKE_LOCK = 1;
-
- // Ensures that the screen is on (but may be dimmed); the keyboard
- // backlight will be allowed to go off. If the user presses the power
- // button, then the SCREEN_DIM_WAKE_LOCK will be implicitly released by
- // the system, causing both the screen and the CPU to be turned off.
- SCREEN_DIM_WAKE_LOCK = 6 [deprecated = true];
-
- // Ensures that the screen is on at full brightness; the keyboard
- // backlight will be allowed to go off. If the user presses the power
- // button, then the SCREEN_BRIGHT_WAKE_LOCK will be implicitly released
- // by the system, causing both the screen and the CPU to be turned off.
- SCREEN_BRIGHT_WAKE_LOCK = 10 [deprecated = true];
-
- // Ensures that the screen and keyboard backlight are on at full
- // brightness. If the user presses the power button, then the
- // FULL_WAKE_LOCK will be implicitly released by the system, causing
- // both the screen and the CPU to be turned off.
- FULL_WAKE_LOCK = 26 [deprecated = true];
-
- // Turns the screen off when the proximity sensor activates. If the
- // proximity sensor detects that an object is nearby, the screen turns
- // off immediately. Shortly after the object moves away, the screen
- // turns on again.
- // A proximity wake lock does not prevent the device from falling asleep
- // unlike FULL_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK and
- // SCREEN_DIM_WAKE_LOCK. If there is no user activity and no other wake
- // locks are held, then the device will fall asleep (and lock) as usual.
- // However, the device will not fall asleep while the screen has been
- // turned off by the proximity sensor because it effectively counts as
- // ongoing user activity.
- PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
-
- // Put the screen in a low power state and allow the CPU to suspend if
- // no other wake locks are held. This is used by the dream manager to
- // implement doze mode. It currently has no effect unless the power
- // manager is in the dozing state.
- DOZE_WAKE_LOCK = 64;
-
- // Keep the device awake enough to allow drawing to occur. This is used
- // by the window manager to allow applications to draw while the system
- // is dozing. It currently has no effect unless the power manager is in
- // the dozing state.
- DRAW_WAKE_LOCK = 128;
-}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index fe65bda365af..8de30f8547a7 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -56,13 +56,13 @@ import "frameworks/base/core/proto/android/service/print.proto";
import "frameworks/base/core/proto/android/service/procstats.proto";
import "frameworks/base/core/proto/android/service/restricted_image.proto";
import "frameworks/base/core/proto/android/service/sensor_service.proto";
-import "frameworks/base/core/proto/android/service/usb.proto";
import "frameworks/base/core/proto/android/util/event_log_tags.proto";
import "frameworks/base/core/proto/android/util/log.proto";
import "frameworks/base/core/proto/android/util/textdump.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/section.proto";
import "frameworks/base/proto/src/ipconnectivity.proto";
+import "frameworks/proto_logging/stats/enums/service/usb.proto";
package android.os;
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 2d2ead455a4d..fa046c6593af 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -20,7 +20,6 @@ package com.android.server.am;
import "frameworks/base/core/proto/android/app/activitymanager.proto";
import "frameworks/base/core/proto/android/app/appexitinfo.proto";
-import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/app/notification.proto";
import "frameworks/base/core/proto/android/app/profilerinfo.proto";
import "frameworks/base/core/proto/android/content/component_name.proto";
@@ -35,6 +34,7 @@ import "frameworks/base/core/proto/android/server/intentresolver.proto";
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/util/common.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/enums.proto";
option java_multiple_files = true;
diff --git a/core/proto/android/server/bluetooth_manager_service.proto b/core/proto/android/server/bluetooth_manager_service.proto
index 998413f05ebe..c33f66a9aeca 100644
--- a/core/proto/android/server/bluetooth_manager_service.proto
+++ b/core/proto/android/server/bluetooth_manager_service.proto
@@ -17,8 +17,8 @@
syntax = "proto2";
package com.android.server;
-import "frameworks/base/core/proto/android/bluetooth/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/bluetooth/enums.proto";
option java_multiple_files = true;
diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp
deleted file mode 100644
index 50c238b96307..000000000000
--- a/core/proto/android/server/connectivity/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "datastallprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "data_stall_event.proto",
- ],
- sdk_version: "system_current",
- // this is part of updatable modules(NetworkStack) which targets 29(Q)
- min_sdk_version: "29",
-}
diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto
deleted file mode 100644
index 787074ba494e..000000000000
--- a/core/proto/android/server/connectivity/data_stall_event.proto
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package com.android.server.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "DataStallEventProto";
-
-enum ProbeResult {
- UNKNOWN = 0;
- VALID = 1;
- INVALID = 2;
- PORTAL = 3;
- PARTIAL = 4;
-}
-
-enum ApBand {
- AP_BAND_UNKNOWN = 0;
- AP_BAND_2GHZ = 1;
- AP_BAND_5GHZ = 2;
- AP_BAND_6GHZ = 3;
-}
-
-// Refer to definition in TelephonyManager.java.
-enum RadioTech {
- RADIO_TECHNOLOGY_UNKNOWN = 0;
- RADIO_TECHNOLOGY_GPRS = 1;
- RADIO_TECHNOLOGY_EDGE = 2;
- RADIO_TECHNOLOGY_UMTS = 3;
- RADIO_TECHNOLOGY_IS95A = 4;
- RADIO_TECHNOLOGY_IS95B = 5;
- RADIO_TECHNOLOGY_1XRTT = 6;
- RADIO_TECHNOLOGY_EVDO_0 = 7;
- RADIO_TECHNOLOGY_EVDO_A = 8;
- RADIO_TECHNOLOGY_HSDPA = 9;
- RADIO_TECHNOLOGY_HSUPA = 10;
- RADIO_TECHNOLOGY_HSPA = 11;
- RADIO_TECHNOLOGY_EVDO_B = 12;
- RADIO_TECHNOLOGY_LTE = 13;
- RADIO_TECHNOLOGY_EHRPD = 14;
- RADIO_TECHNOLOGY_HSPAP = 15;
- RADIO_TECHNOLOGY_GSM = 16;
- RADIO_TECHNOLOGY_TD_SCDMA = 17;
- RADIO_TECHNOLOGY_IWLAN = 18;
- RADIO_TECHNOLOGY_LTE_CA = 19;
- RADIO_TECHNOLOGY_NR = 20;
-}
-
-// Cellular specific information.
-message CellularData {
- // Indicate the radio technology at the time of data stall suspected.
- optional RadioTech rat_type = 1;
- // True if device is in roaming network at the time of data stall suspected.
- optional bool is_roaming = 2;
- // Registered network MccMnc when data stall happen
- optional string network_mccmnc = 3;
- // Indicate the SIM card carrier.
- optional string sim_mccmnc = 4;
- // Signal strength level at the time of data stall suspected.
- optional int32 signal_strength = 5;
-}
-
-// Wifi specific information.
-message WifiData {
- // Signal strength at the time of data stall suspected.
- // RSSI range is between -55 to -110.
- optional int32 signal_strength = 1;
- // AP band.
- optional ApBand wifi_band = 2;
-}
-
-message DnsEvent {
- // The dns return code.
- repeated int32 dns_return_code = 1;
- // Indicate the timestamp of the dns event.
- repeated int64 dns_time = 2;
-}
diff --git a/core/proto/android/server/enums.proto b/core/proto/android/server/enums.proto
deleted file mode 100644
index 89f7010e8d81..000000000000
--- a/core/proto/android/server/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.server;
-
-option java_outer_classname = "ServerProtoEnums";
-option java_multiple_files = true;
-
-enum DeviceIdleModeEnum {
- // Device idle mode - not active.
- DEVICE_IDLE_MODE_OFF = 0;
- // Device idle mode - active in lightweight mode.
- DEVICE_IDLE_MODE_LIGHT = 1;
- // Device idle mode - active in full mode.
- DEVICE_IDLE_MODE_DEEP = 2;
-}
-
-enum ErrorSource {
- ERROR_SOURCE_UNKNOWN = 0;
- // Data app
- DATA_APP = 1;
- // System app
- SYSTEM_APP = 2;
- // System server.
- SYSTEM_SERVER = 3;
-}
diff --git a/core/proto/android/server/job/enums.proto b/core/proto/android/server/job/enums.proto
deleted file mode 100644
index 50fc0310ad99..000000000000
--- a/core/proto/android/server/job/enums.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package com.android.server.job;
-
-// This file is for JobScheduler enums inside the server directory. If you're
-// adding enums for app-side code, use the file in
-// frameworks/base/core/proto/android/app/job.
-option java_outer_classname = "JobServerProtoEnums";
-option java_multiple_files = true;
-
-// Set of constraints that a job potentially needs satisfied before it can run.
-// Defined in
-// frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
-enum ConstraintEnum {
- CONSTRAINT_UNKNOWN = 0;
- CONSTRAINT_CHARGING = 1;
- CONSTRAINT_BATTERY_NOT_LOW = 2;
- CONSTRAINT_STORAGE_NOT_LOW = 3;
- CONSTRAINT_TIMING_DELAY = 4;
- CONSTRAINT_DEADLINE = 5;
- CONSTRAINT_IDLE = 6;
- CONSTRAINT_CONNECTIVITY = 7;
- CONSTRAINT_CONTENT_TRIGGER = 8;
- CONSTRAINT_DEVICE_NOT_DOZING = 9;
- CONSTRAINT_WITHIN_QUOTA = 10;
- CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 11;
-}
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 0e2bd2605836..d18722049109 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -20,7 +20,6 @@ package com.android.server.job;
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/content/clipdata.proto";
import "frameworks/base/core/proto/android/content/component_name.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
@@ -29,10 +28,11 @@ import "frameworks/base/core/proto/android/net/networkrequest.proto";
import "frameworks/base/core/proto/android/os/bundle.proto";
import "frameworks/base/core/proto/android/os/persistablebundle.proto";
import "frameworks/base/core/proto/android/server/appstatetracker.proto";
-import "frameworks/base/core/proto/android/server/job/enums.proto";
import "frameworks/base/core/proto/android/server/statlogger.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/util/quotatracker.proto";
+import "frameworks/proto_logging/stats/enums/app/job/enums.proto";
+import "frameworks/proto_logging/stats/enums/server/job/enums.proto";
message JobSchedulerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/location/enums.proto b/core/proto/android/server/location/enums.proto
deleted file mode 100644
index 943ff181fe14..000000000000
--- a/core/proto/android/server/location/enums.proto
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.server.location;
-
-option java_outer_classname = "ServerLocationProtoEnums";
-option java_multiple_files = true;
-
-// GPS Signal Quality levels,
-// primarily used by location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
-enum GpsSignalQualityEnum {
- GPS_SIGNAL_QUALITY_UNKNOWN = -1;
- GPS_SIGNAL_QUALITY_POOR = 0;
- GPS_SIGNAL_QUALITY_GOOD = 1;
-}
-
-// A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc.
-enum GnssNiType {
- VOICE = 1;
- UMTS_SUPL = 2;
- UMTS_CTRL_PLANE = 3;
- EMERGENCY_SUPL = 4;
-};
-
-// GNSS NI responses, used to define the response in NI structures.
-enum GnssUserResponseType {
- RESPONSE_ACCEPT = 1;
- RESPONSE_DENY = 2;
- RESPONSE_NORESP = 3;
-};
-
-// GNSS NI data encoding scheme.
-enum GnssNiEncodingType {
- ENC_NONE = 0;
- ENC_SUPL_GSM_DEFAULT = 1;
- ENC_SUPL_UTF8 = 2;
- ENC_SUPL_UCS2 = 3;
- ENC_UNKNOWN = -1;
-};
-
-// Protocol stack that initiated the non-framework location request.
-enum NfwProtocolStack {
- // Cellular control plane requests.
- CTRL_PLANE = 0;
- // All types of SUPL requests.
- SUPL = 1;
- // All types of requests from IMS.
- IMS = 10;
- // All types of requests from SIM.
- SIM = 11;
- // Requests from other protocol stacks.
- OTHER_PROTOCOL_STACK = 100;
-};
-
-// Source initiating/receiving the location information.
-enum NfwRequestor {
- // Wireless service provider.
- CARRIER = 0;
- // Device manufacturer.
- OEM = 10;
- // Modem chipset vendor.
- MODEM_CHIPSET_VENDOR = 11;
- // GNSS chipset vendor.
- GNSS_CHIPSET_VENDOR = 12;
- // Other chipset vendor.
- OTHER_CHIPSET_VENDOR = 13;
- // Automobile client.
- AUTOMOBILE_CLIENT = 20;
- // Other sources.
- OTHER_REQUESTOR = 100;
-};
-
-// Indicates whether location information was provided for this request.
-enum NfwResponseType {
- // Request rejected because framework has not given permission for this use case.
- REJECTED = 0;
- // Request accepted but could not provide location because of a failure.
- ACCEPTED_NO_LOCATION_PROVIDED = 1;
- // Request accepted and location provided.
- ACCEPTED_LOCATION_PROVIDED = 2;
-};
-
-// The SUPL mode.
-enum SuplMode {
- // Mobile Station Based.
- MSB = 0x01;
- // Mobile Station Assisted.
- MSA = 0x02;
-};
-
-// Enum that hold the bit masks for various LTE Positioning Profile settings (LPP_PROFILE
-// configuration parameter). If none of the bits in the enum are set, the default setting is
-// Radio Resource Location Protocol(RRLP).
-enum LppProfile {
- // Enable LTE Positioning Protocol user plane.
- USER_PLANE = 0x01;
- // Enable LTE Positioning Protocol Control plane.
- CONTROL_PLANE = 0x02;
-};
-
-// Positioning protocol on A-Glonass system.
-enum GlonassPosProtocol {
- // Radio Resource Control(RRC) control-plane.
- RRC_CPLANE = 0x01;
- // Radio Resource Location user-plane.
- RRLP_CPLANE = 0x02;
- // LTE Positioning Protocol User plane.
- LPP_UPLANE = 0x04;
-};
-
-// Configurations of how GPS functionalities should be locked when user turns off GPS On setting.
-enum GpsLock {
- // Lock Mobile Originated GPS functionalitues.
- MO = 0x01;
- // Lock Network Initiated GPS functionalities.
- NI = 0x02;
-};
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index a2f2c46cba6a..0d23946ebbb8 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -19,16 +19,16 @@ package com.android.server.power;
option java_multiple_files = true;
-import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
-import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/os/looper.proto";
import "frameworks/base/core/proto/android/os/powermanager.proto";
import "frameworks/base/core/proto/android/os/worksource.proto";
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/wirelesschargerdetector.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/app/enums.proto";
+import "frameworks/proto_logging/stats/enums/os/enums.proto";
+import "frameworks/proto_logging/stats/enums/view/enums.proto";
message PowerManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 0453d3f3763d..c4c007d8113b 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -24,7 +24,6 @@ import "frameworks/base/core/proto/android/server/windowcontainerthumbnail.proto
import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
import "frameworks/base/core/proto/android/view/displaycutout.proto";
import "frameworks/base/core/proto/android/view/displayinfo.proto";
-import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/view/surface.proto";
import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
import "frameworks/base/core/proto/android/privacy.proto";
@@ -34,6 +33,8 @@ import "frameworks/base/core/proto/android/view/surfacecontrol.proto";
import "frameworks/base/core/proto/android/view/insetssource.proto";
import "frameworks/base/core/proto/android/view/insetssourcecontrol.proto";
+import "frameworks/proto_logging/stats/enums/view/enums.proto";
+
package com.android.server.wm;
option java_multiple_files = true;
@@ -206,9 +207,10 @@ message DisplayContentProto {
optional WindowStateProto input_method_control_target = 29;
optional WindowStateProto current_focus = 30;
optional ImeInsetsSourceProviderProto ime_insets_source_provider = 31;
- optional bool can_show_ime = 32;
+ optional bool can_show_ime = 32 [deprecated=true];
optional DisplayRotationProto display_rotation = 33;
+ optional int32 ime_policy = 34;
}
/* represents DisplayArea object */
diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto
index 586411f8ad96..3a112e7c85f0 100644
--- a/core/proto/android/service/battery.proto
+++ b/core/proto/android/service/battery.proto
@@ -20,8 +20,8 @@ package android.service.battery;
option java_multiple_files = true;
option java_outer_classname = "BatteryServiceProto";
-import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/os/enums.proto";
message BatteryServiceDumpProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index 7a4c0706e119..57051f07d124 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -21,8 +21,8 @@ option java_multiple_files = true;
option java_outer_classname = "ProcessStatsServiceProto";
import "frameworks/base/core/proto/android/util/common.proto";
-import "frameworks/base/core/proto/android/service/procstats_enum.proto";
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/service/procstats_enum.proto";
/**
* Data from ProcStatsService Dumpsys
diff --git a/core/proto/android/service/procstats_enum.proto b/core/proto/android/service/procstats_enum.proto
deleted file mode 100644
index 2abf3730aa9f..000000000000
--- a/core/proto/android/service/procstats_enum.proto
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service.procstats;
-
-option java_multiple_files = true;
-option java_outer_classname = "ProcessStatsEnums";
-
-enum ScreenState {
- SCREEN_STATE_UNKNOWN = 0;
- SCREEN_STATE_OFF = 1;
- SCREEN_STATE_ON = 2;
-}
-
-enum MemoryState {
- MEMORY_STATE_UNKNOWN = 0;
- MEMORY_STATE_NORMAL = 1; // normal.
- MEMORY_STATE_MODERATE = 2; // moderate memory pressure.
- MEMORY_STATE_LOW = 3; // low memory.
- MEMORY_STATE_CRITICAL = 4; // critical memory.
-}
-
-// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
-// and not frameworks/base/core/java/android/app/ActivityManager.java
-enum ProcessState {
- PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process.
- PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity.
- PROCESS_STATE_TOP = 2;
- // Important foreground process (ime, wallpaper, etc).
- PROCESS_STATE_IMPORTANT_FOREGROUND = 3;
- // Important background process.
- PROCESS_STATE_IMPORTANT_BACKGROUND = 4;
- // Performing backup operation.
- PROCESS_STATE_BACKUP = 5;
- // Background process running a service.
- PROCESS_STATE_SERVICE = 6;
- // Process not running, but would be if there was enough RAM.
- PROCESS_STATE_SERVICE_RESTARTING = 7;
- // Process running a receiver.
- PROCESS_STATE_RECEIVER = 8;
- // Heavy-weight process (currently not used).
- PROCESS_STATE_HEAVY_WEIGHT = 9;
- // Process hosting home/launcher app when not on top.
- PROCESS_STATE_HOME = 10;
- // Process hosting the last app the user was in.
- PROCESS_STATE_LAST_ACTIVITY = 11;
- // Cached process hosting a previous activity.
- PROCESS_STATE_CACHED_ACTIVITY = 12;
- // Cached process hosting a client activity.
- PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 13;
- // Cached process that is empty.
- PROCESS_STATE_CACHED_EMPTY = 14;
-}
-
-enum ServiceOperationState {
- SERVICE_OPERATION_STATE_UNKNOWN = 0;
- SERVICE_OPERATION_STATE_RUNNING = 1;
- SERVICE_OPERATION_STATE_STARTED = 2;
- SERVICE_OPERATION_STATE_FOREGROUND = 3;
- SERVICE_OPERATION_STATE_BOUND = 4;
- SERVICE_OPERATION_STATE_EXECUTING = 5;
-}
-
-// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
-// and not frameworks/base/core/java/android/app/ActivityManager.java
-enum AggregatedProcessState {
- AGGREGATED_PROCESS_STATE_UNKNOWN = 0;
- // Persistent system process; PERSISTENT or PERSISTENT_UI in ActivityManager
- AGGREGATED_PROCESS_STATE_PERSISTENT = 1;
- // Top activity; actually any visible activity; TOP or TOP_SLEEPING in ActivityManager
- AGGREGATED_PROCESS_STATE_TOP = 2;
- // Bound top foreground process; BOUND_TOP or BOUND_FOREGROUND_SERVICE in ActivityManager
- AGGREGATED_PROCESS_STATE_BOUND_TOP_OR_FGS = 3;
- // Important foreground process; FOREGROUND_SERVICE in ActivityManager
- AGGREGATED_PROCESS_STATE_FGS = 4;
- // Important foreground process ; IMPORTANT_FOREGROUND in ActivityManager
- AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND = 5;
- // Various background processes; IMPORTANT_BACKGROUND, TRANSIENT_BACKGROUND, BACKUP, SERVICE,
- // HEAVY_WEIGHT in ActivityManager
- AGGREGATED_PROCESS_STATE_BACKGROUND = 6;
- // Process running a receiver; RECEIVER in ActivityManager
- AGGREGATED_PROCESS_STATE_RECEIVER = 7;
- // Various cached processes; HOME, LAST_ACTIVITY, CACHED_ACTIVITY, CACHED_RECENT,
- // CACHED_ACTIVITY_CLIENT, CACHED_EMPTY in ActivityManager
- AGGREGATED_PROCESS_STATE_CACHED = 8;
-} \ No newline at end of file
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
deleted file mode 100644
index 40c5a85e1f24..000000000000
--- a/core/proto/android/service/usb.proto
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service.usb;
-
-option java_multiple_files = true;
-option java_outer_classname = "UsbServiceProto";
-
-import "frameworks/base/core/proto/android/content/component_name.proto";
-import "frameworks/base/core/proto/android/service/enums.proto";
-import "frameworks/base/core/proto/android/privacy.proto";
-
-message UsbServiceDumpProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceManagerProto device_manager = 1;
- optional UsbHostManagerProto host_manager = 2;
- optional UsbPortManagerProto port_manager = 3;
- optional UsbAlsaManagerProto alsa_manager = 4;
- optional UsbSettingsManagerProto settings_manager = 5;
- optional UsbPermissionsManagerProto permissions_manager = 6;
-}
-
-message UsbDeviceManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbHandlerProto handler = 1;
- optional UsbDebuggingManagerProto debugging_manager = 2;
-}
-
-message UsbHandlerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */
- enum Function {
- FUNCTION_ADB = 1;
- FUNCTION_ACCESSORY = 2;
- FUNCTION_MTP = 4;
- FUNCTION_MIDI = 8;
- FUNCTION_PTP = 16;
- FUNCTION_RNDIS = 32;
- FUNCTION_AUDIO_SOURCE = 64;
- }
-
- repeated Function current_functions = 1;
- optional bool current_functions_applied = 2;
- repeated Function screen_unlocked_functions = 3;
- optional bool screen_locked = 4;
- optional bool connected = 5;
- optional bool configured = 6;
- optional UsbAccessoryProto current_accessory = 7;
- optional bool host_connected = 8;
- optional bool source_power = 9;
- optional bool sink_power = 10;
- optional bool usb_charging = 11;
- optional bool hide_usb_notification = 12;
- optional bool audio_accessory_connected = 13;
- optional bool adb_enabled = 14;
- optional string kernel_state = 15;
- optional string kernel_function_list = 16;
-}
-
-message UsbAccessoryProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string manufacturer = 1;
- optional string model = 2;
- // For "classical" USB-accessories the manufacturer bakes this into the
- // firmware of the device. If an Android phone is configured as accessory, the
- // app that sets up the accessory side of the connection set this. Either way,
- // these are part of the detection protocol, and so they cannot be user set or
- // unique.
- optional string description = 3;
- optional string version = 4;
- optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ];
- // Non-resettable hardware ID.
- optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ];
-}
-
-message UsbDebuggingManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool connected_to_adb = 1;
- // A workstation that connects to the phone for debugging is identified by
- // this key.
- optional string last_key_received = 2 [ (android.privacy).dest = DEST_EXPLICIT ];
- optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ];
- optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ];
-}
-
-message UsbHostManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto default_usb_host_connection_handler = 1;
- repeated UsbDeviceProto devices = 2;
- optional int32 num_connects = 3;
- repeated UsbConnectionRecordProto connections = 4;
-}
-
-message UsbDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Generic USB name, not user-provided.
- optional string name = 1;
- // ID specific to the vendor, not the device.
- optional int32 vendor_id = 2;
- // ID of this product type: Each vendor gives each product a unique ID. E.g.
- // all mice of the same model would have the same ID.
- optional int32 product_id = 3;
- optional int32 class = 4;
- optional int32 subclass = 5;
- optional int32 protocol = 6;
- optional string manufacturer_name = 7;
- optional string product_name = 8;
- optional string version = 9;
- // Non-resettable hardware ID.
- optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ];
- repeated UsbConfigurationProto configurations = 11;
-}
-
-message UsbConfigurationProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // A single USB device can have several configurations and the app accessing
- // the USB device can switch between them. At any time only one can be active.
- // Each configuration can present completely different interfaces end
- // endpoints, i.e. a completely different behavior.
- optional int32 id = 1;
- // Hardware-defined name, not set by the user.
- optional string name = 2;
- optional uint32 attributes = 3;
- optional int32 max_power = 4;
- repeated UsbInterfaceProto interfaces = 5;
-}
-
-message UsbInterfaceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Hardware defined. This is the id used by the app to identify the interface.
- optional int32 id = 1;
- optional int32 alternate_settings = 2;
- optional string name = 3;
- optional int32 class = 4;
- optional int32 subclass = 5;
- optional int32 protocol = 6;
- repeated UsbEndPointProto endpoints = 7;
-}
-
-message UsbEndPointProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 endpoint_number = 1;
- optional android.service.UsbEndPointDirection direction = 2;
- // The address of the endpoint. Needed to read and write to the endpoint.
- optional int32 address = 3;
- optional android.service.UsbEndPointType type = 4;
- optional uint32 attributes = 5;
- optional int32 max_packet_size = 6;
- optional int32 interval = 7;
-}
-
-message UsbConnectionRecordProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string device_address = 1;
- optional android.service.UsbConnectionRecordMode mode = 2;
- optional int64 timestamp = 3;
- optional int32 manufacturer = 4;
- optional int32 product = 5;
- optional UsbIsHeadsetProto is_headset = 6;
-}
-
-message UsbIsHeadsetProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool in = 1;
- optional bool out = 2;
-}
-
-message UsbPortManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional bool is_simulation_active = 1;
- repeated UsbPortInfoProto usb_ports = 2;
-}
-
-message UsbPortInfoProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbPortProto port = 1;
- optional UsbPortStatusProto status = 2;
- optional bool can_change_mode = 3;
- optional bool can_change_power_role = 4;
- optional bool can_change_data_role = 5;
- optional int64 connected_at_millis = 6;
- optional int64 last_connect_duration_millis = 7;
-}
-
-message UsbPortProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */
- enum Mode {
- MODE_NONE = 0;
- MODE_UFP = 1;
- MODE_DFP = 2;
- MODE_DRP = 3;
- MODE_AUDIO_ACCESSORY = 4;
- MODE_DEBUG_ACCESSORY = 8;
- }
-
- // ID of the port. A device (eg: Chromebooks) might have multiple ports.
- optional string id = 1;
- repeated Mode supported_modes = 2;
-}
-
-/* Same as android.hardware.usb.V1_2.Constants.ContaminantPresenceStatus */
-enum ContaminantPresenceStatus {
- CONTAMINANT_STATUS_UNKNOWN = 0;
- CONTAMINANT_STATUS_NOT_SUPPORTED = 1;
- CONTAMINANT_STATUS_DISABLED = 2;
- CONTAMINANT_STATUS_NOT_DETECTED = 3;
- CONTAMINANT_STATUS_DETECTED = 4;
-}
-
-message UsbPortStatusProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */
- enum PowerRole {
- POWER_ROLE_NONE = 0;
- POWER_ROLE_SOURCE = 1;
- POWER_ROLE_SINK = 2;
- }
-
- /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */
- enum DataRole {
- DATA_ROLE_NONE = 0;
- DATA_ROLE_HOST = 1;
- DATA_ROLE_DEVICE = 2;
- }
-
- optional bool connected = 1;
- optional UsbPortProto.Mode current_mode = 2;
- optional PowerRole power_role = 3;
- optional DataRole data_role = 4;
- repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
- optional ContaminantPresenceStatus contaminant_presence_status = 6;
-}
-
-message UsbPortStatusRoleCombinationProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbPortStatusProto.PowerRole power_role = 1;
- optional UsbPortStatusProto.DataRole data_role = 2;
-}
-
-message UsbAlsaManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 cards_parser = 1;
- repeated UsbAlsaDeviceProto alsa_devices = 2;
- repeated UsbMidiDeviceProto midi_devices = 3;
-}
-
-message UsbAlsaDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 card = 1;
- optional int32 device = 2;
- optional string name = 3;
- optional bool has_playback = 4;
- optional bool has_capture = 5;
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string address = 6;
-}
-
-message UsbMidiDeviceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 card = 1;
- optional int32 device = 2;
- // usb device's address, e.g. 001/002, nothing about the phone
- optional string device_address = 3;
-}
-
-message UsbSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated UsbUserSettingsManagerProto user_settings = 1;
- repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2;
-}
-
-message UsbUserSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
- reserved 2; // previously device_permissions, now unused
- reserved 3; // previously accessory_permissions, now unused
- repeated UsbDeviceAttachedActivities device_attached_activities = 4;
- repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
-}
-
-message UsbProfileGroupSettingsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // The user id of the personal profile if the device has a work profile.
- optional int32 parent_user_id = 1;
- repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
- repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
-}
-
-message UsbSettingsDevicePreferenceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceFilterProto filter = 1;
- optional UserPackageProto user_package = 2;
-}
-
-message UsbPermissionsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated UsbUserPermissionsManagerProto user_permissions = 1;
-}
-
-message UsbUserPermissionsManagerProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
-
- repeated UsbDevicePermissionProto device_permissions = 2;
- repeated UsbAccessoryPermissionProto accessory_permissions = 3;
-
- repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
- repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
-}
-
-message UsbDevicePermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Name of device set by manufacturer
- // All devices of the same model have the same name
- optional string device_name = 1;
- repeated int32 uids = 2;
-}
-
-message UsbAccessoryPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Description of accessory set by manufacturer
- // All accessories of the same model have the same description
- optional string accessory_description = 1;
- repeated int32 uids = 2;
-}
-
-message UsbDevicePersistentPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbDeviceFilterProto device_filter = 1;
- repeated UsbUidPermissionProto permission_values = 2;
-}
-
-message UsbAccessoryPersistentPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbAccessoryFilterProto accessory_filter = 1;
- repeated UsbUidPermissionProto permission_values = 2;
-}
-
-message UsbUidPermissionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 uid = 1;
- optional bool is_granted = 2;
-}
-
-message UsbDeviceFilterProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // Mirrors the vendor_id of UsbDeviceProto.
- optional int32 vendor_id = 1;
- optional int32 product_id = 2;
- optional int32 class = 3;
- optional int32 subclass = 4;
- optional int32 protocol = 5;
- optional string manufacturer_name = 6;
- optional string product_name = 7;
- optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ];
-}
-
-message UserPackageProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int32 user_id = 1;
- optional string package_name =2;
-}
-
-message UsbSettingsAccessoryPreferenceProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UsbAccessoryFilterProto filter = 1;
- optional UserPackageProto user_package = 2;
-}
-
-message UsbAccessoryFilterProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional string manufacturer = 1;
- optional string model = 2;
- optional string version = 3;
-}
-
-message UsbDeviceAttachedActivities {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto activity = 1;
- repeated UsbDeviceFilterProto filters = 2;
-}
-
-message UsbAccessoryAttachedActivities {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional android.content.ComponentNameProto activity = 1;
- repeated UsbAccessoryFilterProto filters = 2;
-}
diff --git a/core/proto/android/stats/camera/Android.bp b/core/proto/android/stats/camera/Android.bp
deleted file mode 100644
index cc75e57af87b..000000000000
--- a/core/proto/android/stats/camera/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "cameraprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "*.proto",
- ],
- java_version: "1.8",
- target: {
- android: {
- jarjar_rules: "jarjar-rules.txt",
- },
- host: {
- static_libs: ["libprotobuf-java-nano"],
- }
- },
- sdk_version: "core_platform",
-}
diff --git a/core/proto/android/stats/camera/camera.proto b/core/proto/android/stats/camera/camera.proto
deleted file mode 100644
index 406285551d98..000000000000
--- a/core/proto/android/stats/camera/camera.proto
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.camera;
-option java_multiple_files = true;
-
-message CameraStreamProto {
- // The stream width (in pixels)
- optional int32 width = 1;
- // The stream height (in pixels)
- optional int32 height = 2;
- // The format of the stream
- optional int32 format = 3;
- // The dataspace of the stream
- optional int32 data_space = 4;
- // The usage flag of the stream
- optional int64 usage = 5;
-
- // The number of requests for this stream
- optional int64 request_count = 6;
- // The number of buffer error for this stream
- optional int64 error_count = 7;
- // The capture latency of first request for this stream
- optional int32 first_capture_latency_millis = 8;
-
- // The maximum number of hal buffers
- optional int32 max_hal_buffers = 9;
- // The maximum number of app buffers
- optional int32 max_app_buffers = 10;
-}
diff --git a/core/proto/android/stats/camera/jarjar-rules.txt b/core/proto/android/stats/camera/jarjar-rules.txt
deleted file mode 100644
index 40043a861ceb..000000000000
--- a/core/proto/android/stats/camera/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
deleted file mode 100644
index 5e6ac3cd3ca1..000000000000
--- a/core/proto/android/stats/connectivity/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "networkstackprotos",
- proto: {
- type: "lite",
- },
- srcs: [
- "network_stack.proto",
- ],
- sdk_version: "system_29",
-}
-
-java_library_static {
- name: "tetheringprotos",
- proto: {
- type: "lite",
- },
- srcs: [
- "tethering.proto",
- ],
- apex_available: [
- "com.android.tethering",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/stats/connectivity/network_stack.proto b/core/proto/android/stats/connectivity/network_stack.proto
deleted file mode 100644
index e9726d7ce195..000000000000
--- a/core/proto/android/stats/connectivity/network_stack.proto
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "NetworkStackProto";
-
-enum DhcpRenewResult {
- RR_UNKNOWN = 0;
- RR_SUCCESS = 1;
- RR_ERROR_NAK = 2;
- RR_ERROR_IP_MISMATCH = 3;
- RR_ERROR_IP_EXPIRE = 4;
-}
-
-enum DisconnectCode {
- DC_NONE = 0;
- DC_NORMAL_TERMINATION = 1;
- DC_PROVISIONING_FAIL = 2;
- DC_ERROR_STARTING_IPV4 = 4;
- DC_ERROR_STARTING_IPV6 = 5;
- DC_ERROR_STARTING_IPREACHABILITYMONITOR = 6;
- DC_INVALID_PROVISIONING = 7;
- DC_INTERFACE_NOT_FOUND = 8;
- DC_PROVISIONING_TIMEOUT = 9;
-}
-
-enum TransportType {
- TT_UNKNOWN = 0;
- // Indicates this network uses a Cellular transport
- TT_CELLULAR = 1;
- // Indicates this network uses a Wi-Fi transport
- TT_WIFI = 2;
- // Indicates this network uses a Bluetooth transport
- TT_BLUETOOTH = 3;
- // Indicates this network uses an Ethernet transport
- TT_ETHERNET = 4;
- // Indicates this network uses a Wi-Fi Aware transport
- TT_WIFI_AWARE = 5;
- // Indicates this network uses a LoWPAN transport
- TT_LOWPAN = 6;
- // Indicates this network uses a Cellular+VPN transport
- TT_CELLULAR_VPN = 7;
- // Indicates this network uses a Wi-Fi+VPN transport
- TT_WIFI_VPN = 8;
- // Indicates this network uses a Bluetooth+VPN transport
- TT_BLUETOOTH_VPN = 9;
- // Indicates this network uses an Ethernet+VPN transport
- TT_ETHERNET_VPN = 10;
- // Indicates this network uses a Wi-Fi+Cellular+VPN transport
- TT_WIFI_CELLULAR_VPN = 11;
- // Indicates this network uses for test only
- TT_TEST = 12;
-}
-
-enum DhcpFeature {
- DF_UNKNOWN = 0;
- // DHCP INIT-REBOOT state
- DF_INITREBOOT = 1;
- // DHCP rapid commit option
- DF_RAPIDCOMMIT = 2;
- // Duplicate address detection
- DF_DAD = 3;
- // Fast initial Link setup
- DF_FILS = 4;
-}
-
-enum HostnameTransResult {
- HTR_UNKNOWN = 0;
- HTR_SUCCESS = 1;
- HTR_FAILURE = 2;
- HTR_DISABLE = 3;
-}
-
-enum ProbeResult {
- PR_UNKNOWN = 0;
- PR_SUCCESS = 1;
- PR_FAILURE = 2;
- PR_PORTAL = 3;
- // DNS query for the probe host returned a private IP address
- PR_PRIVATE_IP_DNS = 4;
-}
-
-enum ValidationResult {
- VR_UNKNOWN = 0;
- VR_SUCCESS = 1;
- VR_FAILURE = 2;
- VR_PORTAL = 3;
- VR_PARTIAL = 4;
-}
-
-enum ProbeType {
- PT_UNKNOWN = 0;
- PT_DNS = 1;
- PT_HTTP = 2;
- PT_HTTPS = 3;
- PT_PAC = 4;
- PT_FALLBACK = 5;
- PT_PRIVDNS = 6;
- PT_CAPPORT_API = 7;
-}
-
-// The Dhcp error code is defined in android.net.metrics.DhcpErrorEvent
-enum DhcpErrorCode {
- ET_UNKNOWN = 0;
- ET_L2_ERROR = 1;
- ET_L3_ERROR = 2;
- ET_L4_ERROR = 3;
- ET_DHCP_ERROR = 4;
- ET_MISC_ERROR = 5;
- /* Reserve for error type
- // ET_L2_ERROR_TYPE = ET_L2_ERROR << 8;
- ET_L2_ERROR_TYPE = 256;
- // ET_L3_ERROR_TYPE = ET_L3_ERROR << 8;
- ET_L3_ERROR_TYPE = 512;
- // ET_L4_ERROR_TYPE = ET_L4_ERROR << 8;
- ET_L4_ERROR_TYPE = 768;
- // ET_DHCP_ERROR_TYPE = ET_DHCP_ERROR << 8;
- ET_DHCP_ERROR_TYPE = 1024;
- // ET_MISC_ERROR_TYPE = ET_MISC_ERROR << 8;
- ET_MISC_ERROR_TYPE = 1280;
- */
- // ET_L2_TOO_SHORT = (ET_L2_ERROR_TYPE | 0x1) << 16;
- ET_L2_TOO_SHORT = 16842752;
- // ET_L2_WRONG_ETH_TYPE = (ET_L2_ERROR_TYPE | 0x2) << 16;
- ET_L2_WRONG_ETH_TYPE = 16908288;
- // ET_L3_TOO_SHORT = (ET_L3_ERROR_TYPE | 0x1) << 16;
- ET_L3_TOO_SHORT = 33619968;
- // ET_L3_NOT_IPV4 = (ET_L3_ERROR_TYPE | 0x2) << 16;
- ET_L3_NOT_IPV4 = 33685504;
- // ET_L3_INVALID_IP = (ET_L3_ERROR_TYPE | 0x3) << 16;
- ET_L3_INVALID_IP = 33751040;
- // ET_L4_NOT_UDP = (ET_L4_ERROR_TYPE | 0x1) << 16;
- ET_L4_NOT_UDP = 50397184;
- // ET_L4_WRONG_PORT = (ET_L4_ERROR_TYPE | 0x2) << 16;
- ET_L4_WRONG_PORT = 50462720;
- // ET_BOOTP_TOO_SHORT = (ET_DHCP_ERROR_TYPE | 0x1) << 16;
- ET_BOOTP_TOO_SHORT = 67174400;
- // ET_DHCP_BAD_MAGIC_COOKIE = (ET_DHCP_ERROR_TYPE | 0x2) << 16;
- ET_DHCP_BAD_MAGIC_COOKIE = 67239936;
- // ET_DHCP_INVALID_OPTION_LENGTH = (ET_DHCP_ERROR_TYPE | 0x3) << 16;
- ET_DHCP_INVALID_OPTION_LENGTH = 67305472;
- // ET_DHCP_NO_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x4) << 16;
- ET_DHCP_NO_MSG_TYPE = 67371008;
- // ET_DHCP_UNKNOWN_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x5) << 16;
- ET_DHCP_UNKNOWN_MSG_TYPE = 67436544;
- // ET_DHCP_NO_COOKIE = (ET_DHCP_ERROR_TYPE | 0x6) << 16;
- ET_DHCP_NO_COOKIE = 67502080;
- // ET_BUFFER_UNDERFLOW = (ET_MISC_ERROR_TYPE | 0x1) << 16;
- ET_BUFFER_UNDERFLOW = 83951616;
- // ET_RECEIVE_ERROR = (ET_MISC_ERROR_TYPE | 0x2) << 16;
- ET_RECEIVE_ERROR = 84017152;
- // ET_PARSING_ERROR = (ET_MISC_ERROR_TYPE | 0x3) << 16;
- ET_PARSING_ERROR = 84082688;
-}
-
-enum NetworkQuirkEvent {
- QE_UNKNOWN = 0;
- QE_IPV6_PROVISIONING_ROUTER_LOST = 1;
-}
-
-message NetworkStackEventData {
-
-}
-
diff --git a/core/proto/android/stats/connectivity/tethering.proto b/core/proto/android/stats/connectivity/tethering.proto
deleted file mode 100644
index 13f0b8c44fb5..000000000000
--- a/core/proto/android/stats/connectivity/tethering.proto
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.connectivity;
-option java_multiple_files = true;
-option java_outer_classname = "TetheringProto";
-
-enum ErrorCode {
- EC_NO_ERROR = 0;
- EC_UNKNOWN_IFACE = 1;
- EC_SERVICE_UNAVAIL = 2;
- EC_UNSUPPORTED = 3;
- EC_UNAVAIL_IFACE = 4;
- EC_INTERNAL_ERROR = 5;
- EC_TETHER_IFACE_ERROR = 6;
- EC_UNTETHER_IFACE_ERROR = 7;
- EC_ENABLE_FORWARDING_ERROR = 8;
- EC_DISABLE_FORWARDING_ERROR = 9;
- EC_IFACE_CFG_ERROR = 10;
- EC_PROVISIONING_FAILED = 11;
- EC_DHCPSERVER_ERROR = 12;
- EC_ENTITLEMENT_UNKNOWN = 13;
- EC_NO_CHANGE_TETHERING_PERMISSION = 14;
- EC_NO_ACCESS_TETHERING_PERMISSION = 15;
- EC_UNKNOWN_TYPE = 16;
-}
-
-enum DownstreamType {
- // Unspecific tethering type.
- DS_UNSPECIFIED = 0;
- // Wifi tethering type.
- DS_TETHERING_WIFI = 1;
- // USB tethering type.
- DS_TETHERING_USB = 2;
- // Bluetooth tethering type.
- DS_TETHERING_BLUETOOTH = 3;
- // Wifi P2p tethering type.
- DS_TETHERING_WIFI_P2P = 4;
- // NCM (Network Control Model) local tethering type.
- DS_TETHERING_NCM = 5;
- // Ethernet tethering type.
- DS_TETHERING_ETHERNET = 6;
-}
-
-enum UpstreamType {
- UT_UNKNOWN = 0;
- // Indicates upstream using a Cellular transport.
- UT_CELLULAR = 1;
- // Indicates upstream using a Wi-Fi transport.
- UT_WIFI = 2;
- // Indicates upstream using a Bluetooth transport.
- UT_BLUETOOTH = 3;
- // Indicates upstream using an Ethernet transport.
- UT_ETHERNET = 4;
- // Indicates upstream using a Wi-Fi Aware transport.
- UT_WIFI_AWARE = 5;
- // Indicates upstream using a LoWPAN transport.
- UT_LOWPAN = 6;
- // Indicates upstream using a Cellular+VPN transport.
- UT_CELLULAR_VPN = 7;
- // Indicates upstream using a Wi-Fi+VPN transport.
- UT_WIFI_VPN = 8;
- // Indicates upstream using a Bluetooth+VPN transport.
- UT_BLUETOOTH_VPN = 9;
- // Indicates upstream using an Ethernet+VPN transport.
- UT_ETHERNET_VPN = 10;
- // Indicates upstream using a Wi-Fi+Cellular+VPN transport.
- UT_WIFI_CELLULAR_VPN = 11;
- // Indicates upstream using for test only.
- UT_TEST = 12;
- // Indicates upstream using DUN capability + Cellular transport.
- UT_DUN_CELLULAR = 13;
-}
-
-enum UserType {
- // Unknown.
- USER_UNKNOWN = 0;
- // Settings.
- USER_SETTINGS = 1;
- // System UI.
- USER_SYSTEMUI = 2;
- // Google mobile service.
- USER_GMS = 3;
-}
diff --git a/core/proto/android/stats/devicepolicy/Android.bp b/core/proto/android/stats/devicepolicy/Android.bp
deleted file mode 100644
index 5fb278a34dae..000000000000
--- a/core/proto/android/stats/devicepolicy/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2018 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.
-
-java_library_static {
- name: "devicepolicyprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "*.proto",
- ],
- java_version: "1.8",
- target: {
- android: {
- jarjar_rules: "jarjar-rules.txt",
- },
- host: {
- static_libs: ["libprotobuf-java-nano"],
- }
- },
- sdk_version: "core_platform",
-}
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
deleted file mode 100644
index 7c1a04944d68..000000000000
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.devicepolicy;
-option java_multiple_files = true;
-
-/**
- * Id for device policy features.
- */
-enum EventId {
- SET_PASSWORD_QUALITY = 1;
- SET_PASSWORD_MINIMUM_LENGTH = 2;
- SET_PASSWORD_MINIMUM_NUMERIC = 3;
- SET_PASSWORD_MINIMUM_NON_LETTER = 4;
- SET_PASSWORD_MINIMUM_LETTERS = 5;
- SET_PASSWORD_MINIMUM_LOWER_CASE = 6;
- SET_PASSWORD_MINIMUM_UPPER_CASE = 7;
- SET_PASSWORD_MINIMUM_SYMBOLS = 8;
- SET_KEYGUARD_DISABLED_FEATURES = 9;
- LOCK_NOW = 10;
- WIPE_DATA_WITH_REASON = 11;
- ADD_USER_RESTRICTION = 12;
- REMOVE_USER_RESTRICTION = 13;
- SET_SECURE_SETTING = 14;
- SET_SECURITY_LOGGING_ENABLED = 15;
- RETRIEVE_SECURITY_LOGS = 16;
- RETRIEVE_PRE_REBOOT_SECURITY_LOGS = 17;
- SET_PERMISSION_POLICY = 18;
- SET_PERMISSION_GRANT_STATE = 19;
- INSTALL_KEY_PAIR = 20;
- INSTALL_CA_CERT = 21;
- CHOOSE_PRIVATE_KEY_ALIAS = 22;
- REMOVE_KEY_PAIR = 23;
- UNINSTALL_CA_CERTS = 24;
- SET_CERT_INSTALLER_PACKAGE = 25;
- SET_ALWAYS_ON_VPN_PACKAGE = 26;
- SET_PERMITTED_INPUT_METHODS = 27;
- SET_PERMITTED_ACCESSIBILITY_SERVICES = 28;
- SET_SCREEN_CAPTURE_DISABLED = 29;
- SET_CAMERA_DISABLED = 30;
- QUERY_SUMMARY_FOR_USER = 31;
- QUERY_SUMMARY = 32;
- QUERY_DETAILS = 33;
- REBOOT = 34;
- SET_MASTER_VOLUME_MUTED = 35;
- SET_AUTO_TIME_REQUIRED = 36;
- SET_KEYGUARD_DISABLED = 37;
- SET_STATUS_BAR_DISABLED = 38;
- SET_ORGANIZATION_COLOR = 39;
- SET_PROFILE_NAME = 40;
- SET_USER_ICON = 41;
- SET_DEVICE_OWNER_LOCK_SCREEN_INFO = 42;
- SET_SHORT_SUPPORT_MESSAGE = 43;
- SET_LONG_SUPPORT_MESSAGE = 44;
- SET_CROSS_PROFILE_CONTACTS_SEARCH_DISABLED = 45;
- SET_CROSS_PROFILE_CALLER_ID_DISABLED = 46;
- SET_BLUETOOTH_CONTACT_SHARING_DISABLED = 47;
- ADD_CROSS_PROFILE_INTENT_FILTER = 48;
- ADD_CROSS_PROFILE_WIDGET_PROVIDER = 49;
- SET_SYSTEM_UPDATE_POLICY = 50;
- SET_LOCKTASK_MODE_ENABLED = 51;
- ADD_PERSISTENT_PREFERRED_ACTIVITY = 52;
- REQUEST_BUGREPORT = 53;
- GET_WIFI_MAC_ADDRESS = 54;
- REQUEST_QUIET_MODE_ENABLED = 55;
- WORK_PROFILE_LOCATION_CHANGED = 56;
- DO_USER_INFO_CLICKED = 57;
- TRANSFER_OWNERSHIP = 58;
- GENERATE_KEY_PAIR = 59;
- SET_KEY_PAIR_CERTIFICATE = 60;
- SET_KEEP_UNINSTALLED_PACKAGES = 61;
- SET_APPLICATION_RESTRICTIONS = 62;
- SET_APPLICATION_HIDDEN = 63;
- ENABLE_SYSTEM_APP = 64;
- ENABLE_SYSTEM_APP_WITH_INTENT = 65;
- INSTALL_EXISTING_PACKAGE = 66;
- SET_UNINSTALL_BLOCKED = 67;
- SET_PACKAGES_SUSPENDED = 68;
- ON_LOCK_TASK_MODE_ENTERING = 69;
- SET_CROSS_PROFILE_CALENDAR_PACKAGES = 70;
- GET_USER_PASSWORD_COMPLEXITY_LEVEL = 72;
- INSTALL_SYSTEM_UPDATE = 73;
- INSTALL_SYSTEM_UPDATE_ERROR = 74;
- IS_MANAGED_KIOSK = 75;
- IS_UNATTENDED_MANAGED_KIOSK = 76;
- PROVISIONING_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 77;
- PROVISIONING_PERSISTENT_DEVICE_OWNER = 78;
-
- // existing Tron logs to be migrated to statsd
- PROVISIONING_ENTRY_POINT_NFC = 79;
- PROVISIONING_ENTRY_POINT_QR_CODE = 80;
- PROVISIONING_ENTRY_POINT_CLOUD_ENROLLMENT = 81;
- PROVISIONING_ENTRY_POINT_ADB = 82;
- PROVISIONING_ENTRY_POINT_TRUSTED_SOURCE = 83;
- PROVISIONING_DPC_PACKAGE_NAME = 84;
- PROVISIONING_DPC_INSTALLED_BY_PACKAGE = 85;
- PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS = 86;
- PROVISIONING_PREPROVISIONING_ACTIVITY_TIME_MS = 87;
- PROVISIONING_ENCRYPT_DEVICE_ACTIVITY_TIME_MS = 88;
- PROVISIONING_WEB_ACTIVITY_TIME_MS = 89;
- PROVISIONING_TRAMPOLINE_ACTIVITY_TIME_MS = 90 [deprecated=true];
- PROVISIONING_POST_ENCRYPTION_ACTIVITY_TIME_MS = 91 [deprecated=true];
- PROVISIONING_FINALIZATION_ACTIVITY_TIME_MS = 92 [deprecated=true];
- PROVISIONING_NETWORK_TYPE = 93;
- PROVISIONING_ACTION = 94;
- PROVISIONING_EXTRAS = 95;
- PROVISIONING_COPY_ACCOUNT_TASK_MS = 96;
- PROVISIONING_CREATE_PROFILE_TASK_MS = 97;
- PROVISIONING_START_PROFILE_TASK_MS = 98;
- PROVISIONING_DOWNLOAD_PACKAGE_TASK_MS = 99;
- PROVISIONING_INSTALL_PACKAGE_TASK_MS = 100;
- PROVISIONING_CANCELLED = 101;
- PROVISIONING_ERROR = 102;
- PROVISIONING_COPY_ACCOUNT_STATUS = 103;
- PROVISIONING_TOTAL_TASK_TIME_MS = 104;
- PROVISIONING_SESSION_STARTED = 105;
- PROVISIONING_SESSION_COMPLETED = 106;
- PROVISIONING_TERMS_ACTIVITY_TIME_MS = 107;
- PROVISIONING_TERMS_COUNT = 108;
- PROVISIONING_TERMS_READ = 109;
-
- SEPARATE_PROFILE_CHALLENGE_CHANGED = 110;
- SET_GLOBAL_SETTING = 111;
- INSTALL_PACKAGE = 112;
- UNINSTALL_PACKAGE = 113;
- WIFI_SERVICE_ADD_NETWORK_SUGGESTIONS = 114;
- WIFI_SERVICE_ADD_OR_UPDATE_NETWORK = 115;
- QUERY_SUMMARY_FOR_DEVICE = 116;
- REMOVE_CROSS_PROFILE_WIDGET_PROVIDER = 117;
- ESTABLISH_VPN = 118;
- SET_NETWORK_LOGGING_ENABLED = 119;
- RETRIEVE_NETWORK_LOGS = 120;
- PROVISIONING_PREPARE_TOTAL_TIME_MS = 121;
- PROVISIONING_PREPARE_STARTED = 122;
- PROVISIONING_PREPARE_COMPLETED = 123;
- PROVISIONING_FLOW_TYPE = 124;
- CROSS_PROFILE_APPS_GET_TARGET_USER_PROFILES = 125;
- CROSS_PROFILE_APPS_START_ACTIVITY_AS_USER = 126;
- SET_AUTO_TIME = 127;
- SET_AUTO_TIME_ZONE = 128;
- SET_USER_CONTROL_DISABLED_PACKAGES = 129;
- SET_FACTORY_RESET_PROTECTION = 130;
- SET_COMMON_CRITERIA_MODE = 131;
- ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS = 132;
- SET_TIME = 133;
- SET_TIME_ZONE = 134;
- SET_PERSONAL_APPS_SUSPENDED = 135;
- SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF = 136;
- COMP_TO_ORG_OWNED_PO_MIGRATED = 137;
- SET_CROSS_PROFILE_PACKAGES = 138;
- SET_INTERACT_ACROSS_PROFILES_APP_OP = 139;
- GET_CROSS_PROFILE_PACKAGES = 140;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_TRUE = 141;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 142;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_WHITELIST = 143;
- CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 144;
- CAN_INTERACT_ACROSS_PROFILES_TRUE = 145;
- CAN_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 146;
- CAN_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 147;
- CREATE_CROSS_PROFILE_INTENT = 148;
- IS_MANAGED_PROFILE = 149;
- START_ACTIVITY_BY_INTENT = 150;
- BIND_CROSS_PROFILE_SERVICE = 151;
- PROVISIONING_DPC_SETUP_STARTED = 152;
- PROVISIONING_DPC_SETUP_COMPLETED = 153;
- PROVISIONING_ORGANIZATION_OWNED_MANAGED_PROFILE = 154;
- RESOLVER_CROSS_PROFILE_TARGET_OPENED = 155;
- RESOLVER_SWITCH_TABS = 156;
- RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED = 157;
- RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL= 158;
- RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK= 159;
- RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED= 160;
- RESOLVER_AUTOLAUNCH_CROSS_PROFILE_TARGET = 161;
- CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP = 162;
- CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS = 163;
- CROSS_PROFILE_SETTINGS_PAGE_ADMIN_RESTRICTED = 164;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_WORK_APP = 165;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_PERSONAL_APP = 166;
- CROSS_PROFILE_SETTINGS_PAGE_MISSING_INSTALL_BANNER_INTENT = 167;
- CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED = 168;
- CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_NO_INTENT_CLICKED = 169;
- CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED = 170;
- CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT = 171;
- CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED = 172;
- DOCSUI_EMPTY_STATE_NO_PERMISSION = 173;
- DOCSUI_EMPTY_STATE_QUIET_MODE = 174;
- DOCSUI_LAUNCH_OTHER_APP = 175;
- DOCSUI_PICK_RESULT = 176;
-}
diff --git a/core/proto/android/stats/devicepolicy/jarjar-rules.txt b/core/proto/android/stats/devicepolicy/jarjar-rules.txt
deleted file mode 100644
index 40043a861ceb..000000000000
--- a/core/proto/android/stats/devicepolicy/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp
deleted file mode 100644
index 1e8c76314448..000000000000
--- a/core/proto/android/stats/dnsresolver/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "dnsresolverprotosnano",
- proto: {
- type: "nano",
- },
- srcs: [
- "dns_resolver.proto",
- ],
- sdk_version: "system_current",
-}
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
deleted file mode 100644
index b17d12c9c315..000000000000
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.dnsresolver;
-
-enum EventType {
- EVENT_UNKNOWN = 0;
- EVENT_GETADDRINFO = 1;
- EVENT_GETHOSTBYNAME = 2;
- EVENT_GETHOSTBYADDR = 3;
- EVENT_RES_NSEND = 4;
-}
-
-// The return value of the DNS resolver for each DNS lookups.
-// bionic/libc/include/netdb.h
-// system/netd/resolv/include/netd_resolv/resolv.h
-enum ReturnCode {
- RC_EAI_NO_ERROR = 0;
- RC_EAI_ADDRFAMILY = 1;
- RC_EAI_AGAIN = 2;
- RC_EAI_BADFLAGS = 3;
- RC_EAI_FAIL = 4;
- RC_EAI_FAMILY = 5;
- RC_EAI_MEMORY = 6;
- RC_EAI_NODATA = 7;
- RC_EAI_NONAME = 8;
- RC_EAI_SERVICE = 9;
- RC_EAI_SOCKTYPE = 10;
- RC_EAI_SYSTEM = 11;
- RC_EAI_BADHINTS = 12;
- RC_EAI_PROTOCOL = 13;
- RC_EAI_OVERFLOW = 14;
- RC_RESOLV_INTERNAL_ERROR = 254;
- RC_RESOLV_TIMEOUT = 255;
- RC_EAI_MAX = 256;
-}
-
-enum NsRcode {
- NS_R_NO_ERROR = 0; // No error occurred.
- NS_R_FORMERR = 1; // Format error.
- NS_R_SERVFAIL = 2; // Server failure.
- NS_R_NXDOMAIN = 3; // Name error.
- NS_R_NOTIMPL = 4; // Unimplemented.
- NS_R_REFUSED = 5; // Operation refused.
- // these are for BIND_UPDATE
- NS_R_YXDOMAIN = 6; // Name exists
- NS_R_YXRRSET = 7; // RRset exists
- NS_R_NXRRSET = 8; // RRset does not exist
- NS_R_NOTAUTH = 9; // Not authoritative for zone
- NS_R_NOTZONE = 10; // Zone of record different from zone section
- NS_R_MAX = 11;
- // Define rcode=12~15(UNASSIGNED) in rcode enum type.
- // Some DNS Servers might return undefined code to devices.
- // Without the enum definition, that would be noise for our dashboard.
- NS_R_UNASSIGNED12 = 12; // Unassigned
- NS_R_UNASSIGNED13 = 13; // Unassigned
- NS_R_UNASSIGNED14 = 14; // Unassigned
- NS_R_UNASSIGNED15 = 15; // Unassigned
- // The following are EDNS extended rcodes
- NS_R_BADVERS = 16;
- // The following are TSIG errors
- // NS_R_BADSIG = 16,
- NS_R_BADKEY = 17;
- NS_R_BADTIME = 18;
- NS_R_INTERNAL_ERROR = 254;
- NS_R_TIMEOUT = 255;
-}
-
-// Currently defined type values for resources and queries.
-enum NsType {
- NS_T_INVALID = 0; // Cookie.
- NS_T_A = 1; // Host address.
- NS_T_NS = 2; // Authoritative server.
- NS_T_MD = 3; // Mail destination.
- NS_T_MF = 4; // Mail forwarder.
- NS_T_CNAME = 5; // Canonical name.
- NS_T_SOA = 6; // Start of authority zone.
- NS_T_MB = 7; // Mailbox domain name.
- NS_T_MG = 8; // Mail group member.
- NS_T_MR = 9; // Mail rename name.
- NS_T_NULL = 10; // Null resource record.
- NS_T_WKS = 11; // Well known service.
- NS_T_PTR = 12; // Domain name pointer.
- NS_T_HINFO = 13; // Host information.
- NS_T_MINFO = 14; // Mailbox information.
- NS_T_MX = 15; // Mail routing information.
- NS_T_TXT = 16; // Text strings.
- NS_T_RP = 17; // Responsible person.
- NS_T_AFSDB = 18; // AFS cell database.
- NS_T_X25 = 19; // X_25 calling address.
- NS_T_ISDN = 20; // ISDN calling address.
- NS_T_RT = 21; // Router.
- NS_T_NSAP = 22; // NSAP address.
- NS_T_NSAP_PTR = 23; // Reverse NSAP lookup (deprecated).
- NS_T_SIG = 24; // Security signature.
- NS_T_KEY = 25; // Security key.
- NS_T_PX = 26; // X.400 mail mapping.
- NS_T_GPOS = 27; // Geographical position (withdrawn).
- NS_T_AAAA = 28; // IPv6 Address.
- NS_T_LOC = 29; // Location Information.
- NS_T_NXT = 30; // Next domain (security).
- NS_T_EID = 31; // Endpoint identifier.
- NS_T_NIMLOC = 32; // Nimrod Locator.
- NS_T_SRV = 33; // Server Selection.
- NS_T_ATMA = 34; // ATM Address
- NS_T_NAPTR = 35; // Naming Authority PoinTeR
- NS_T_KX = 36; // Key Exchange
- NS_T_CERT = 37; // Certification record
- NS_T_A6 = 38; // IPv6 address (experimental)
- NS_T_DNAME = 39; // Non-terminal DNAME
- NS_T_SINK = 40; // Kitchen sink (experimentatl)
- NS_T_OPT = 41; // EDNS0 option (meta-RR)
- NS_T_APL = 42; // Address prefix list (RFC 3123)
- NS_T_DS = 43; // Delegation Signer
- NS_T_SSHFP = 44; // SSH Fingerprint
- NS_T_IPSECKEY = 45; // IPSEC Key
- NS_T_RRSIG = 46; // RRset Signature
- NS_T_NSEC = 47; // Negative security
- NS_T_DNSKEY = 48; // DNS Key
- NS_T_DHCID = 49; // Dynamic host configuratin identifier
- NS_T_NSEC3 = 50; // Negative security type 3
- NS_T_NSEC3PARAM = 51; // Negative security type 3 parameters
- NS_T_HIP = 55; // Host Identity Protocol
- NS_T_SPF = 99; // Sender Policy Framework
- NS_T_TKEY = 249; // Transaction key
- NS_T_TSIG = 250; // Transaction signature.
- NS_T_IXFR = 251; // Incremental zone transfer.
- NS_T_AXFR = 252; // Transfer zone of authority.
- NS_T_MAILB = 253; // Transfer mailbox records.
- NS_T_MAILA = 254; // Transfer mail agent records.
- NS_T_ANY = 255; // Wildcard match.
- NS_T_ZXFR = 256; // BIND-specific, nonstandard.
- NS_T_DLV = 32769; // DNSSEC look-aside validatation.
- NS_T_MAX = 65536;
-}
-
-enum IpVersion {
- IV_UNKNOWN = 0;
- IV_IPV4 = 1;
- IV_IPV6 = 2;
-}
-
-enum Protocol {
- PROTO_UNKNOWN = 0;
- PROTO_UDP = 1;
- PROTO_TCP = 2;
- PROTO_DOT = 3;
-}
-
-enum PrivateDnsModes {
- PDM_UNKNOWN = 0;
- PDM_OFF = 1;
- PDM_OPPORTUNISTIC = 2;
- PDM_STRICT = 3;
-}
-
-enum NetworkType {
- NT_UNKNOWN = 0;
- // Indicates this network uses a Cellular transport.
- NT_CELLULAR = 1;
- // Indicates this network uses a Wi-Fi transport.
- NT_WIFI = 2;
- // Indicates this network uses a Bluetooth transport.
- NT_BLUETOOTH = 3;
- // Indicates this network uses an Ethernet transport.
- NT_ETHERNET = 4;
- // Indicates this network uses a VPN transport, now deprecated.
- NT_VPN = 5 [deprecated=true];
- // Indicates this network uses a Wi-Fi Aware transport.
- NT_WIFI_AWARE = 6;
- // Indicates this network uses a LoWPAN transport.
- NT_LOWPAN = 7;
- // Indicates this network uses a Cellular+VPN transport.
- NT_CELLULAR_VPN = 8;
- // Indicates this network uses a Wi-Fi+VPN transport.
- NT_WIFI_VPN = 9;
- // Indicates this network uses a Bluetooth+VPN transport.
- NT_BLUETOOTH_VPN = 10;
- // Indicates this network uses an Ethernet+VPN transport.
- NT_ETHERNET_VPN = 11;
- // Indicates this network uses a Wi-Fi+Cellular+VPN transport.
- NT_WIFI_CELLULAR_VPN = 12;
-}
-
-enum CacheStatus{
- // the cache can't handle that kind of queries.
- // or the answer buffer is too small.
- CS_UNSUPPORTED = 0;
- // the cache doesn't know about this query.
- CS_NOTFOUND = 1;
- // the cache found the answer.
- CS_FOUND = 2;
- // Don't do anything on cache.
- CS_SKIP = 3;
-}
-
-// The enum LinuxErrno is defined in the following 2 files.
-// 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h
-// 2. bionic/libc/kernel/uapi/asm-generic/errno.h
-enum LinuxErrno {
- SYS_NO_ERROR = 0;
- SYS_EPERM = 1; // Not super-user
- SYS_ENOENT = 2; // No such file or directory
- SYS_ESRCH = 3; // No such process
- SYS_EINTR = 4; // Interrupted system call
- SYS_EIO = 5; // I/O error
- SYS_ENXIO = 6; // No such device or address
- SYS_E2BIG = 7; // Arg list too long
- SYS_ENOEXEC = 8; // Exec format error
- SYS_EBADF = 9; // Bad file number
- SYS_ECHILD = 10; // No children
- SYS_EAGAIN = 11; // No more processes
- SYS_ENOMEM = 12; // Not enough core
- SYS_EACCES = 13; // Permission denied
- SYS_EFAULT = 14; // Bad address
- SYS_ENOTBLK = 15; // Block device required
- SYS_EBUSY = 16; // Mount device busy
- SYS_EEXIST = 17; // File exists
- SYS_EXDEV = 18; // Cross-device link
- SYS_ENODEV = 19; // No such device
- SYS_ENOTDIR = 20; // Not a directory
- SYS_EISDIR = 21; // Is a directory
- SYS_EINVAL = 22; // Invalid argument
- SYS_ENFILE = 23; // Too many open files in system
- SYS_EMFILE = 24; // Too many open files
- SYS_ENOTTY = 25; // Not a typewriter
- SYS_ETXTBSY = 26; // Text file busy
- SYS_EFBIG = 27; // File too large
- SYS_ENOSPC = 28; // No space left on device
- SYS_ESPIPE = 29; // Illegal seek
- SYS_EROFS = 30; // Read only file system
- SYS_EMLINK = 31; // Too many links
- SYS_EPIPE = 32; // Broken pipe
- SYS_EDOM = 33; // Math arg out of domain of func
- SYS_ERANGE = 34; // Math result not representable
- SYS_EDEADLOCK = 35; // File locking deadlock error
- SYS_ENAMETOOLONG = 36; // File or path name too long
- SYS_ENOLCK = 37; // No record locks available
- SYS_ENOSYS = 38; // Function not implemented
- SYS_ENOTEMPTY = 39; // Directory not empty
- SYS_ELOOP = 40; // Too many symbolic links
- SYS_ENOMSG = 42; // No message of desired type
- SYS_EIDRM = 43; // Identifier removed
- SYS_ECHRNG = 44; // Channel number out of range
- SYS_EL2NSYNC = 45; // Level 2 not synchronized
- SYS_EL3HLT = 46; // Level 3 halted
- SYS_EL3RST = 47; // Level 3 reset
- SYS_ELNRNG = 48; // Link number out of range
- SYS_EUNATCH = 49; // rotocol driver not attached
- SYS_ENOCSI = 50; // No CSI structure available
- SYS_EL2HLT = 51; // Level 2 halted
- SYS_EBADE = 52; // Invalid exchange
- SYS_EBADR = 53; // Invalid request descriptor
- SYS_EXFULL = 54; // Exchange full
- SYS_ENOANO = 55; // No anode
- SYS_EBADRQC = 56; // Invalid request code
- SYS_EBADSLT = 57; // Invalid slot
- SYS_EBFONT = 59; // Bad font file fmt
- SYS_ENOSTR = 60; // Device not a stream
- SYS_ENODATA = 61; // No data (for no delay io)
- SYS_ETIME = 62; // Timer expired
- SYS_ENOSR = 63; // Out of streams resources
- SYS_ENONET = 64; // Machine is not on the network
- SYS_ENOPKG = 65; // Package not installed
- SYS_EREMOTE = 66; // The object is remote
- SYS_ENOLINK = 67; // The link has been severed
- SYS_EADV = 68; // Advertise error
- SYS_ESRMNT = 69; // Srmount error
- SYS_ECOMM = 70; // Communication error on send
- SYS_EPROTO = 71; // Protocol error
- SYS_EMULTIHOP = 72; // Multihop attempted
- SYS_EDOTDOT = 73; // Cross mount point (not really error)
- SYS_EBADMSG = 74; // Trying to read unreadable message
- SYS_EOVERFLOW = 75; // Value too large for defined data type
- SYS_ENOTUNIQ = 76; // Given log. name not unique
- SYS_EBADFD = 77; // f.d. invalid for this operation
- SYS_EREMCHG = 78; // Remote address changed
- SYS_ELIBACC = 79; // Can't access a needed shared lib
- SYS_ELIBBAD = 80; // Accessing a corrupted shared lib
- SYS_ELIBSCN = 81; // .lib section in a.out corrupted
- SYS_ELIBMAX = 82; // Attempting to link in too many libs
- SYS_ELIBEXEC = 83; // Attempting to exec a shared library
- SYS_EILSEQ = 84;
- SYS_ERESTART = 85;
- SYS_ESTRPIPE = 86;
- SYS_EUSERS = 87;
- SYS_ENOTSOCK = 88; // Socket operation on non-socket
- SYS_EDESTADDRREQ = 89; // Destination address required
- SYS_EMSGSIZE = 90; // Message too long
- SYS_EPROTOTYPE = 91; // Protocol wrong type for socket
- SYS_ENOPROTOOPT = 92; // Protocol not available
- SYS_EPROTONOSUPPORT = 93; // Unknown protocol
- SYS_ESOCKTNOSUPPORT = 94; // Socket type not supported
- SYS_EOPNOTSUPP = 95; // Operation not supported on transport endpoint
- SYS_EPFNOSUPPORT = 96; // Protocol family not supported
- SYS_EAFNOSUPPORT = 97; // Address family not supported by protocol family
- SYS_EADDRINUSE = 98; // Address already in use
- SYS_EADDRNOTAVAIL = 99; // Address not available
- SYS_ENETDOWN = 100; // Network interface is not configured
- SYS_ENETUNREACH = 101; // Network is unreachable
- SYS_ENETRESET = 102;
- SYS_ECONNABORTED = 103; // Connection aborted
- SYS_ECONNRESET = 104; // Connection reset by peer
- SYS_ENOBUFS = 105; // No buffer space available
- SYS_EISCONN = 106; // Socket is already connected
- SYS_ENOTCONN = 107; // Socket is not connected
- SYS_ESHUTDOWN = 108; // Can't send after socket shutdown
- SYS_ETOOMANYREFS = 109;
- SYS_ETIMEDOUT = 110; // Connection timed out
- SYS_ECONNREFUSED = 111; // Connection refused
- SYS_EHOSTDOWN = 112; // Host is down
- SYS_EHOSTUNREACH = 113; // Host is unreachable
- SYS_EALREADY = 114; // Socket already connected
- SYS_EINPROGRESS = 115; // Connection already in progress
- SYS_ESTALE = 116;
- SYS_EUCLEAN = 117;
- SYS_ENOTNAM = 118;
- SYS_ENAVAIL = 119;
- SYS_EISNAM = 120;
- SYS_EREMOTEIO = 121;
- SYS_EDQUOT = 122;
- SYS_ENOMEDIUM = 123; // No medium (in tape drive)
- SYS_EMEDIUMTYPE = 124;
- SYS_ECANCELED = 125;
- SYS_ENOKEY = 126;
- SYS_EKEYEXPIRED = 127;
- SYS_EKEYREVOKED = 128;
- SYS_EKEYREJECTED = 129;
- SYS_EOWNERDEAD = 130;
- SYS_ENOTRECOVERABLE = 131;
- SYS_ERFKILL = 132;
- SYS_EHWPOISON = 133;
-}
-
-message DnsQueryEvent {
- optional android.stats.dnsresolver.NsRcode rcode = 1;
-
- optional android.stats.dnsresolver.NsType type = 2;
-
- optional android.stats.dnsresolver.CacheStatus cache_hit = 3;
-
- optional android.stats.dnsresolver.IpVersion ip_version = 4;
-
- optional android.stats.dnsresolver.Protocol protocol = 5;
-
- // Number of DNS query retry times
- optional int32 retry_times = 6;
-
- // Ordinal number of name server.
- optional int32 dns_server_index = 7;
-
- // Used only by TCP and DOT. True for new connections.
- optional bool connected = 8;
-
- optional int32 latency_micros = 9;
-
- optional android.stats.dnsresolver.LinuxErrno linux_errno = 10;
-}
-
-message DnsQueryEvents {
- repeated DnsQueryEvent dns_query_event = 1;
-}
diff --git a/core/proto/android/stats/docsui/docsui_enums.proto b/core/proto/android/stats/docsui/docsui_enums.proto
deleted file mode 100644
index 5963f6a7f938..000000000000
--- a/core/proto/android/stats/docsui/docsui_enums.proto
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.docsui;
-option java_multiple_files = true;
-
-enum LaunchAction {
- UNKNOWN = 0;
- OPEN = 1;
- CREATE = 2;
- GET_CONTENT = 3;
- OPEN_TREE = 4;
- PICK_COPY_DEST = 5;
- BROWSE = 6;
- OTHER = 7;
-}
-
-enum MimeType {
- MIME_UNKNOWN = 0;
- MIME_NONE = 1;
- MIME_ANY = 2;
- MIME_APPLICATION = 3;
- MIME_AUDIO = 4;
- MIME_IMAGE = 5;
- MIME_MESSAGE = 6;
- MIME_MULTIPART = 7;
- MIME_TEXT = 8;
- MIME_VIDEO = 9;
- MIME_OTHER = 10;
-}
-
-enum Root {
- ROOT_UNKNOWN = 0;
- ROOT_NONE = 1;
- ROOT_OTHER_DOCS_PROVIDER = 2;
- ROOT_AUDIO = 3;
- ROOT_DEVICE_STORAGE = 4;
- ROOT_DOWNLOADS = 5;
- ROOT_HOME = 6;
- ROOT_IMAGES = 7;
- ROOT_RECENTS = 8;
- ROOT_VIDEOS = 9;
- ROOT_MTP = 10;
- ROOT_THIRD_PARTY_APP = 11;
- ROOT_DOCUMENTS = 12;
-}
-
-enum ContextScope {
- SCOPE_UNKNOWN = 0;
- SCOPE_FILES = 1;
- SCOPE_PICKER = 2;
-}
-
-enum Provider {
- PROVIDER_UNKNOWN = 0;
- PROVIDER_SYSTEM = 1;
- PROVIDER_EXTERNAL = 2;
-}
-
-enum FileOperation {
- OP_UNKNOWN = 0;
- OP_OTHER = 1;
- OP_COPY = 2;
- OP_COPY_INTRA_PROVIDER = 3;
- OP_COPY_SYSTEM_PROVIDER = 4;
- OP_COPY_EXTERNAL_PROVIDER = 5;
- OP_MOVE = 6;
- OP_MOVE_INTRA_PROVIDER = 7;
- OP_MOVE_SYSTEM_PROVIDER = 8;
- OP_MOVE_EXTERNAL_PROVIDER = 9;
- OP_DELETE = 10;
- OP_RENAME = 11;
- OP_CREATE_DIR = 12;
- OP_OTHER_ERROR = 13;
- OP_DELETE_ERROR = 14;
- OP_MOVE_ERROR = 15;
- OP_COPY_ERROR = 16;
- OP_RENAME_ERROR = 17;
- OP_CREATE_DIR_ERROR = 18;
- OP_COMPRESS_INTRA_PROVIDER = 19;
- OP_COMPRESS_SYSTEM_PROVIDER = 20;
- OP_COMPRESS_EXTERNAL_PROVIDER = 21;
- OP_EXTRACT_INTRA_PROVIDER = 22;
- OP_EXTRACT_SYSTEM_PROVIDER = 23;
- OP_EXTRACT_EXTERNAL_PROVIDER = 24;
- OP_COMPRESS_ERROR = 25;
- OP_EXTRACT_ERROR = 26;
-}
-
-enum SubFileOperation {
- SUB_OP_UNKNOWN = 0;
- SUB_OP_QUERY_DOC = 1;
- SUB_OP_QUERY_CHILD = 2;
- SUB_OP_OPEN_FILE = 3;
- SUB_OP_READ_FILE = 4;
- SUB_OP_CREATE_DOC = 5;
- SUB_OP_WRITE_FILE = 6;
- SUB_OP_DELETE_DOC = 7;
- SUB_OP_OBTAIN_STREAM_TYPE = 8;
- SUB_OP_QUICK_MOVE = 9;
- SUB_OP_QUICK_COPY = 10;
-}
-
-enum CopyMoveOpMode {
- MODE_UNKNOWN = 0;
- MODE_PROVIDER = 1;
- MODE_CONVERTED = 2;
- MODE_CONVENTIONAL = 3;
-}
-
-enum Authority {
- AUTH_UNKNOWN = 0;
- AUTH_OTHER = 1;
- AUTH_MEDIA = 2;
- AUTH_STORAGE_INTERNAL = 3;
- AUTH_STORAGE_EXTERNAL = 4;
- AUTH_DOWNLOADS = 5;
- AUTH_MTP = 6;
-}
-
-enum UserAction {
- ACTION_UNKNOWN = 0;
- ACTION_OTHER = 1;
- ACTION_GRID = 2;
- ACTION_LIST = 3;
- ACTION_SORT_NAME = 4;
- ACTION_SORT_DATE = 5;
- ACTION_SORT_SIZE = 6;
- ACTION_SORT_TYPE = 7;
- ACTION_SEARCH = 8;
- ACTION_SHOW_SIZE = 9;
- ACTION_HIDE_SIZE = 10;
- ACTION_SETTINGS = 11;
- ACTION_COPY_TO = 12;
- ACTION_MOVE_TO = 13;
- ACTION_DELETE = 14;
- ACTION_RENAME = 15;
- ACTION_CREATE_DIR = 16;
- ACTION_SELECT_ALL = 17;
- ACTION_SHARE = 18;
- ACTION_OPEN = 19;
- ACTION_SHOW_ADVANCED = 20;
- ACTION_HIDE_ADVANCED = 21;
- ACTION_NEW_WINDOW = 22;
- ACTION_PASTE_CLIPBOARD = 23;
- ACTION_COPY_CLIPBOARD = 24;
- ACTION_DRAG_N_DROP = 25;
- ACTION_DRAG_N_DROP_MULTI_WINDOW = 26;
- ACTION_CUT_CLIPBOARD = 27;
- ACTION_COMPRESS = 28;
- ACTION_EXTRACT_TO = 29;
- ACTION_VIEW_IN_APPLICATION = 30;
- ACTION_INSPECTOR = 31;
- ACTION_SEARCH_CHIP = 32;
- ACTION_SEARCH_HISTORY = 33;
-}
-
-enum InvalidScopedAccess {
- SCOPED_DIR_ACCESS_UNKNOWN = 0;
- SCOPED_DIR_ACCESS_INVALID_ARGUMENTS = 1;
- SCOPED_DIR_ACCESS_INVALID_DIRECTORY = 2;
- SCOPED_DIR_ACCESS_ERROR = 3;
- SCOPED_DIR_ACCESS_DEPRECATED = 4;
-}
-
-enum SearchType {
- TYPE_UNKNOWN = 0;
- TYPE_CHIP_IMAGES = 1;
- TYPE_CHIP_AUDIOS = 2;
- TYPE_CHIP_VIDEOS = 3;
- TYPE_CHIP_DOCS = 4;
- TYPE_SEARCH_HISTORY = 5;
- TYPE_SEARCH_STRING = 6;
- TYPE_CHIP_LARGE_FILES = 7;
- TYPE_CHIP_FROM_THIS_WEEK = 8;
-}
-
-enum SearchMode {
- SEARCH_UNKNOWN = 0;
- SEARCH_KEYWORD = 1;
- SEARCH_CHIPS = 2;
- SEARCH_KEYWORD_N_CHIPS = 3;
-}
diff --git a/core/proto/android/stats/hdmi/enums.proto b/core/proto/android/stats/hdmi/enums.proto
deleted file mode 100644
index acb8899fbdd9..000000000000
--- a/core/proto/android/stats/hdmi/enums.proto
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.hdmi;
-option java_multiple_files = true;
-option java_outer_classname = "HdmiStatsEnums";
-
-// HDMI CEC logical addresses.
-// Values correspond to "CEC Table 5 Logical Addresses" in the HDMI CEC 1.4b spec.
-enum LogicalAddress {
- LOGICAL_ADDRESS_UNKNOWN = -1;
- TV = 0;
- RECORDING_DEVICE_1 = 1;
- RECORDING_DEVICE_2 = 2;
- TUNER_1 = 3;
- PLAYBACK_DEVICE_1 = 4;
- AUDIO_SYSTEM = 5;
- TUNER_2 = 6;
- TUNER_3 = 7;
- PLAYBACK_DEVICE_2 = 8;
- RECORDING_DEVICE_3 = 9;
- TUNER_4 = 10;
- PLAYBACK_DEVICE_3 = 11;
- RESERVED_1 = 12;
- RESERVED_2 = 13;
- SPECIFIC_USE = 14;
- UNREGISTERED_OR_BROADCAST = 15;
-}
-
-// The relationship between two paths.
-// Values correspond exactly to PathRelationship in com.android.server.hdmi.Constants.
-enum PathRelationship {
- RELATIONSHIP_TO_ACTIVE_SOURCE_UNKNOWN = 0;
- DIFFERENT_BRANCH = 1;
- ANCESTOR = 2;
- DESCENDANT = 3;
- SIBLING = 4;
- SAME = 5;
-}
-
-// The result of attempting to send a HDMI CEC message.
-// Values correspond to the constants in android.hardware.tv.cec.V1_0.SendMessageResult,
-// offset by 10.
-enum SendMessageResult {
- SEND_MESSAGE_RESULT_UNKNOWN = 0;
- SUCCESS = 10;
- NACK = 11;
- BUSY = 12;
- FAIL = 13;
-}
-
-// Whether a HDMI CEC message is sent from this device, to this device, or neither.
-enum MessageDirection {
- MESSAGE_DIRECTION_UNKNOWN = 0;
- MESSAGE_DIRECTION_OTHER = 1; // None of the other options.
- OUTGOING = 2; // Sent from this device.
- INCOMING = 3; // Sent to this device.
- TO_SELF = 4; // Sent from this device, to this device. Indicates a bug.
-}
-
-// User control commands. Each value can represent an individual command, or a set of commands.
-// Values correspond to "CEC Table 30 UI Command Codes" in the HDMI CEC 1.4b spec, offset by 0x100.
-enum UserControlPressedCommand {
- USER_CONTROL_PRESSED_COMMAND_UNKNOWN = 0;
-
- // Represents all codes that are not represented by another value.
- USER_CONTROL_PRESSED_COMMAND_OTHER = 1;
-
- // Represents all number codes (codes 0x1E through 0x29).
- NUMBER = 2;
-
- // Navigation
- SELECT = 0x100;
- UP = 0x101;
- DOWN = 0x102;
- LEFT = 0x103;
- RIGHT = 0x104;
- RIGHT_UP = 0x105;
- RIGHT_DOWN = 0x106;
- LEFT_UP = 0x107;
- LEFT_DOWN = 0x108;
- EXIT = 0x10D;
-
- // Volume
- VOLUME_UP = 0x141;
- VOLUME_DOWN = 0x142;
- VOLUME_MUTE = 0x143;
-
- // Power
- POWER = 0x140;
- POWER_TOGGLE = 0x16B;
- POWER_OFF = 0x16C;
- POWER_ON = 0x16D;
-}
-
-// Reason parameter of the <Feature Abort> message.
-// Values correspond to "CEC Table 29 Operand Descriptions" in the HDMI CEC 1.4b spec,
-// offset by 10.
-enum FeatureAbortReason {
- FEATURE_ABORT_REASON_UNKNOWN = 0;
- UNRECOGNIZED_OPCODE = 10;
- NOT_IN_CORRECT_MODE_TO_RESPOND = 11;
- CANNOT_PROVIDE_SOURCE = 12;
- INVALID_OPERAND = 13;
- REFUSED = 14;
- UNABLE_TO_DETERMINE = 15;
-} \ No newline at end of file
diff --git a/core/proto/android/stats/intelligence/enums.proto b/core/proto/android/stats/intelligence/enums.proto
deleted file mode 100644
index 0c210e3fd08f..000000000000
--- a/core/proto/android/stats/intelligence/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.intelligence;
-option java_outer_classname = "IntelligenceStatsEnums";
-
-enum Status {
- // The value wasn't set.
- // protoc requires enum values to be unique by package rather than enum type.
- // This forces us to prefix the enum values.
- STATUS_UNKNOWN = 0;
- // The event succeeded.
- STATUS_SUCCEEDED = 1;
- // The event had an error.
- STATUS_FAILED = 2;
-}
-
-enum EventType {
- // The value wasn't set.
- EVENT_UNKNOWN = 0;
- // ContentSuggestionsService classifyContentSelections call.
- EVENT_CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL = 1;
- // ContentSuggestionsService suggestContentSelections call.
- EVENT_CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL = 2;
-}
diff --git a/core/proto/android/stats/launcher/Android.bp b/core/proto/android/stats/launcher/Android.bp
deleted file mode 100644
index 976a0b8634a3..000000000000
--- a/core/proto/android/stats/launcher/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2018 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.
-
-java_library {
- name: "launcherprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
-
-java_library {
- name: "launcherprotoslite",
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto
deleted file mode 100644
index fc177d57b193..000000000000
--- a/core/proto/android/stats/launcher/launcher.proto
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.launcher;
-option java_multiple_files = true;
-
-enum LauncherAction {
- DEFAULT_ACTION = 0;
- LAUNCH_APP = 1;
- LAUNCH_TASK = 2;
- DISMISS_TASK = 3;
- LONGPRESS = 4;
- DRAGDROP = 5;
- SWIPE_UP = 6;
- SWIPE_DOWN = 7;
- SWIPE_LEFT = 8;
- SWIPE_RIGHT = 9;
-}
-
-enum LauncherState {
- LAUNCHER_STATE_UNSPECIFIED = 0;
- BACKGROUND = 1;
- HOME = 2;
- OVERVIEW = 3;
- ALLAPPS = 4;
- UNCHANGED = 5;
-}
-
-message LauncherTarget {
- enum Type {
- NONE = 0;
- ITEM_TYPE = 1;
- CONTROL_TYPE = 2;
- CONTAINER_TYPE = 3;
- }
- enum Item {
- DEFAULT_ITEM = 0;
- APP_ICON = 1;
- SHORTCUT = 2;
- WIDGET = 3;
- FOLDER_ICON = 4;
- DEEPSHORTCUT = 5;
- SEARCHBOX = 6;
- EDITTEXT = 7;
- NOTIFICATION = 8;
- TASK = 9;
- }
- enum Container {
- DEFAULT_CONTAINER = 0;
- HOTSEAT = 1;
- FOLDER = 2;
- PREDICTION = 3;
- SEARCHRESULT = 4;
- }
- enum Control {
- DEFAULT_CONTROL = 0;
- MENU = 1;
- UNINSTALL = 2;
- REMOVE = 3;
- }
- optional Type type = 1;
- optional Item item = 2;
- optional Container container = 3;
- optional Control control = 4;
- optional string launch_component = 5;
- optional int32 page_id = 6;
- optional int32 grid_x = 7;
- optional int32 grid_y = 8;
-}
-
-message LauncherExtension {
- repeated LauncherTarget src_target = 1;
- repeated LauncherTarget dst_target = 2;
-}
diff --git a/core/proto/android/stats/location/location_enums.proto b/core/proto/android/stats/location/location_enums.proto
deleted file mode 100644
index 553c01c5d0dd..000000000000
--- a/core/proto/android/stats/location/location_enums.proto
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.location;
-option java_outer_classname = "LocationStatsEnums";
-
-
-// APIs from LocationManagerService
-enum LocationManagerServiceApi {
- API_UNKNOWN = 0;
- API_REQUEST_LOCATION_UPDATES = 1;
- API_ADD_GNSS_MEASUREMENTS_LISTENER = 2;
- API_REGISTER_GNSS_STATUS_CALLBACK = 3;
- API_REQUEST_GEOFENCE = 4;
- API_SEND_EXTRA_COMMAND = 5;
-}
-
-enum UsageState {
- USAGE_STARTED = 0;
- USAGE_ENDED = 1;
-}
-
-// Type of location providers
-enum ProviderType {
- PROVIDER_UNKNOWN = 0;
- PROVIDER_NETWORK = 1;
- PROVIDER_GPS = 2;
- PROVIDER_PASSIVE = 3;
- PROVIDER_FUSED = 4;
-}
-
-// Type of Callback passed in for this API
-enum CallbackType {
- CALLBACK_UNKNOWN = 0;
- // Current API does not need a callback, e.g. sendExtraCommand
- CALLBACK_NOT_APPLICABLE = 1;
- CALLBACK_LISTENER = 2;
- CALLBACK_PENDING_INTENT = 3;
-}
-
-// Possible values for mQuality field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum LocationRequestQuality {
- QUALITY_UNKNOWN = 0;
- ACCURACY_FINE = 100;
- ACCURACY_BLOCK = 102;
- ACCURACY_CITY = 104;
- POWER_NONE = 200;
- POWER_LOW = 201;
- POWER_HIGH = 203;
-}
-
-// Bucketized values for interval field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum LocationRequestIntervalBucket {
- INTERVAL_UNKNOWN = 0;
- INTERVAL_BETWEEN_0_SEC_AND_1_SEC = 1;
- INTERVAL_BETWEEN_1_SEC_AND_5_SEC = 2;
- INTERVAL_BETWEEN_5_SEC_AND_1_MIN = 3;
- INTERVAL_BETWEEN_1_MIN_AND_10_MIN = 4;
- INTERVAL_BETWEEN_10_MIN_AND_1_HOUR = 5;
- INTERVAL_LARGER_THAN_1_HOUR = 6;
-}
-
-// Bucketized values for small displacement field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-// Value in meters.
-enum SmallestDisplacementBucket {
- DISTANCE_UNKNOWN = 0;
- DISTANCE_ZERO = 1;
- DISTANCE_BETWEEN_0_AND_100 = 2;
- DISTANCE_LARGER_THAN_100 = 3;
-}
-
-// Bucketized values for expire_in field in
-// frameworks/base/location/java/android/location/LocationRequest.java
-enum ExpirationBucket {
- EXPIRATION_UNKNOWN = 0;
- EXPIRATION_BETWEEN_0_AND_20_SEC = 1;
- EXPIRATION_BETWEEN_20_SEC_AND_1_MIN = 2;
- EXPIRATION_BETWEEN_1_MIN_AND_10_MIN = 3;
- EXPIRATION_BETWEEN_10_MIN_AND_1_HOUR = 4;
- EXPIRATION_LARGER_THAN_1_HOUR = 5;
- EXPIRATION_NO_EXPIRY = 6;
-}
-
-// Bucketized values for radius field in
-// frameworks/base/location/java/android/location/Geofence.java
-// Value in meters.
-enum GeofenceRadiusBucket {
- RADIUS_UNKNOWN = 0;
- RADIUS_BETWEEN_0_AND_100 = 1;
- RADIUS_BETWEEN_100_AND_200 = 2;
- RADIUS_BETWEEN_200_AND_300 = 3;
- RADIUS_BETWEEN_300_AND_1000 = 4;
- RADIUS_BETWEEN_1000_AND_10000 = 5;
- RADIUS_LARGER_THAN_100000 = 6;
- RADIUS_NEGATIVE = 7;
-}
-
-// Caller Activity Importance.
-enum ActivityImportance {
- IMPORTANCE_UNKNOWN = 0;
- IMPORTANCE_TOP = 1;
- IMPORTANCE_FORGROUND_SERVICE = 2;
- IMPORTANCE_BACKGROUND = 3;
-}
diff --git a/core/proto/android/stats/mediametrics/mediametrics.proto b/core/proto/android/stats/mediametrics/mediametrics.proto
deleted file mode 100644
index eb8a3b19f263..000000000000
--- a/core/proto/android/stats/mediametrics/mediametrics.proto
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.mediametrics;
-
-/**
- * Track how we arbitrate between microphone/input requests.
- * Logged from
- * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp
- * Next Tag: 10
- */
-message AudioPolicyData {
- optional int32 status = 1;
- optional string request_source = 2;
- optional string request_package = 3;
- optional int32 request_session = 4;
- optional string request_device = 5;
- optional string active_source = 6;
- optional string active_package = 7;
- optional int32 active_session = 8;
- optional string active_device = 9;
-}
-
-/**
- * Track properties of audio recording
- * Logged from
- * frameworks/av/media/libaudioclient/AudioRecord.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp
- * Next Tag: 16
- */
-message AudioRecordData {
- optional string encoding = 1;
- optional string source = 2;
- optional int32 latency = 3;
- optional int32 samplerate = 4;
- optional int32 channels = 5;
- optional int64 created_millis = 6;
- optional int64 duration_millis = 7;
- optional int32 count = 8;
- optional int32 error_code = 9;
- optional string error_function = 10;
- optional int32 port_id = 11;
- optional int32 frame_count = 12;
- optional string attributes = 13;
- optional int64 channel_mask = 14;
- optional int64 start_count = 15;
-
-}
-
-/**
- * Track audio thread performance data
- * Logged from
- * frameworks/av/media/libnblog/ReportPerformance.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp
- * Next Tag: 28
- */
-message AudioThreadData {
- optional string type = 1;
- optional int32 framecount = 2;
- optional int32 samplerate = 3;
- optional string work_millis_hist = 4;
- optional string latency_millis_hist = 5;
- optional string warmup_millis_hist = 6;
- optional int64 underruns = 7;
- optional int64 overruns = 8;
- optional int64 active_millis = 9;
- optional int64 duration_millis = 10;
-
- optional int32 id = 11;
- optional int32 port_id = 12;
- optional int32 sample_rate = 13;
- optional int64 channel_mask = 14;
- optional string encoding = 15;
- optional int32 frame_count = 16;
- optional string output_device = 17;
- optional string input_device = 18;
- optional double io_jitter_mean_millis = 19;
- optional double io_jitter_stddev_millis = 20;
- optional double process_time_mean_millis = 21;
- optional double process_time_stddev_millis = 22;
- optional double timestamp_jitter_mean_millis = 23;
- optional double timestamp_jitter_stddev_millis = 24;
- optional double latency_mean_millis = 25;
- optional double latency_stddev_millis = 26;
-
-}
-
-/**
- * Track audio track playback data
- * Logged from
- * frameworks/av/media/libaudioclient/AudioTrack.cpp
- * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp
- * Next Tag: 12
- */
-message AudioTrackData {
- optional string stream_type = 1;
- optional string content_type = 2;
- optional string track_usage = 3;
- optional int32 sample_rate = 4;
- optional int64 channel_mask = 5;
-
- optional int32 underrun_frames = 6;
- optional int32 startup_glitch = 7;
-
- optional int32 port_id = 8;
- optional string encoding = 9;
- optional int32 frame_count = 10;
- optional string attributes = 11;
-
-
-}
-
-/**
- * Track Media Codec usage
- * Logged from:
- * frameworks/av/media/libstagefright/MediaCodec.cpp
- * frameworks/av/services/mediaanalytics/statsd_codec.cpp
- * Next Tag: 26
- */
-message CodecData {
- optional string codec = 1;
- optional string mime = 2;
- optional string mode = 3;
- optional int32 encoder = 4;
- optional int32 secure = 5;
- optional int32 width = 6;
- optional int32 height = 7;
- optional int32 rotation = 8;
- optional int32 crypto = 9;
- optional int32 profile = 10;
- optional int32 level = 11;
- optional int32 max_width = 12;
- optional int32 max_height = 13;
- optional int32 error_code = 14;
- optional string error_state = 15;
- optional int64 latency_max = 16;
- optional int64 latency_min = 17;
- optional int64 latency_avg = 18;
- optional int64 latency_count = 19;
- optional int64 latency_unknown = 20;
- optional int32 queue_input_buffer_error = 21;
- optional int32 queue_secure_input_buffer_error = 22;
- optional string bitrate_mode = 23;
- optional int32 bitrate = 24;
- optional int64 lifetime_millis = 25;
-}
-
-/**
- * Track Media Extractor (pulling video/audio streams out of containers) usage
- * Logged from:
- * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp
- * frameworks/av/services/mediaanalytics/statsd_extractor.cpp
- * Next Tag: 5
- */
-message ExtractorData {
- optional string format = 1;
- optional string mime = 2;
- optional int32 tracks = 3;
-
- enum EntryPoint {
- UNSET = 0; // For backwards compatibility with clients that don't
- // collect the entry point.
- SDK = 1;
- NDK_WITH_JVM = 2;
- NDK_NO_JVM = 3;
- OTHER = 4; // For extractor users that don't make use of the APIs.
- }
-
- optional EntryPoint entry_point = 4 [default = UNSET];
-}
-
-/**
- * Track Media Player usage
- * this handles both nuplayer and nuplayer2
- * Logged from:
- * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
- * frameworks/av/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
- * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp
- * Next Tag: 21
- */
-message NuPlayerData {
- optional string whichPlayer = 1;
-
- optional string video_mime = 2;
- optional string video_codec = 3;
- optional int32 width = 4;
- optional int32 height = 5;
- optional int64 frames = 6;
- optional int64 frames_dropped = 7;
- optional double framerate = 8;
- optional string audio_mime = 9;
- optional string audio_codec = 10;
- optional int64 duration_millis = 11;
- optional int64 playing_millis = 12;
- optional int32 error = 13;
- optional int32 error_code = 14;
- optional string error_state = 15;
- optional string data_source_type = 16;
- optional int64 rebuffering_millis = 17;
- optional int32 rebuffers = 18;
- optional int32 rebuffer_at_exit = 19;
- optional int64 frames_dropped_startup = 20;
-}
-
-/**
- * Track information about recordings (e.g. camcorder)
- * Logged from
- * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp
- * frameworks/av/services/mediaanalytics/if_statsd.cpp
- * Next Tag: 22
- */
-message RecorderData {
- optional string audio_mime = 1;
- optional string video_mime = 2;
- optional int32 video_profile = 3;
- optional int32 video_level = 4;
- optional int32 width = 5;
- optional int32 height = 6;
- optional int32 rotation = 7;
- optional int32 framerate = 8;
- optional int32 capture_fps = 9;
- optional double capture_fps_enable = 10;
- optional int64 duration_millis = 11;
- optional int64 paused_millis = 12;
- optional int32 paused_count = 13;
- optional int32 audio_bitrate = 14;
- optional int32 audio_channels = 15;
- optional int32 audio_samplerate = 16;
- optional int32 movie_timescale = 17;
- optional int32 audio_timescale = 18;
- optional int32 video_timescale = 19;
- optional int32 video_bitrate = 20;
- optional int32 iframe_interval = 21;
-}
-
-enum StreamType {
- STREAM_TYPE_UNKNOWN = 0;
- STREAM_TYPE_OTHER = 1;
- STREAM_TYPE_PROGRESSIVE = 2;
- STREAM_TYPE_DASH = 3;
- STREAM_TYPE_HLS = 4;
- STREAM_TYPE_SS = 5;
-}
-
-enum DrmType {
- DRM_TYPE_NONE = 0;
- DRM_TYPE_OTHER = 1;
- DRM_TYPE_PLAY_READY = 2;
- DRM_TYPE_WV_L1 = 3;
- DRM_TYPE_WV_L3 = 4;
-}
-
-enum PlaybackType {
- PLAYBACK_TYPE_VOD = 0;
- PLAYBACK_TYPE_LIVE = 1;
- PLAYBACK_TYPE_OTHER = 2;
-}
-
-enum ContentType {
- CONTENT_TYPE_MAIN = 0;
- CONTENT_TYPE_AD = 1;
- CONTENT_TYPE_OTHER = 2;
-}
-
-enum StreamSourceType {
- STREAM_SOURCE_UNKNOWN = 0;
- STREAM_SOURCE_NETWORK = 1;
- STREAM_SOURCE_DEVICE = 2;
- STREAM_SOURCE_MIXED = 3;
-}
-enum NetworkType {
- NETWORK_TYPE_NONE = 0;
- NETWORK_TYPE_OTHER = 1;
- NETWORK_TYPE_WIFI = 2;
- NETWORK_TYPE_ETHERNET = 3;
- NETWORK_TYPE_2G = 4;
- NETWORK_TYPE_3G = 5;
- NETWORK_TYPE_4G = 6;
- NETWORK_TYPE_5G_NSA = 7;
- NETWORK_TYPE_5G_SA = 8;
-}
-
-enum PlaybackState {
- // Playback has not started (initial state)
- NOT_STARTED = 0;
- // Playback is buffering in the background for initial playback start
- JOINING_BACKGROUND = 1;
- // Playback is buffering in the foreground for initial playback start
- JOINING_FOREGROUND = 2;
- // Playback is actively playing
- PLAYING = 3;
- // Playback is paused but ready to play
- PAUSED = 4;
- // Playback is handling a seek
- SEEKING = 5;
- // Playback is buffering to resume active playback
- BUFFERING = 6;
- // Playback is buffering while paused
- PAUSED_BUFFERING = 7;
- // Playback is suppressed (e.g. due to audio focus loss)
- SUPPRESSED = 8;
- // Playback is suppressed (e.g. due to audio focus loss) while buffering to resume a
- // playback
- SUPPRESSED_BUFFERING = 9;
- // Playback has reached the end of the media
- ENDED = 10;
- // Playback is stopped and can be restarted
- STOPPED = 11;
- // Playback is stopped due a fatal error and can be retried
- FAILED = 12;
- // Playback is interrupted by an ad
- INTERRUPTED_BY_AD = 13;
- // Playback is abandoned before reaching the end of the media
- ABANDONED = 14;
-}
-
-enum PlaybackErrorCode {
- ERROR_CODE_UNKNOWN = 0;
- ERROR_CODE_OTHER = 1;
- ERROR_CODE_RUNTIME = 2;
-}
-
-enum TrackType {
- AUDIO = 0;
- VIDEO = 1;
- TEXT = 2;
-}
-enum TrackState {
- OFF = 0;
- ON = 1;
-}
-enum TrackChangeReason {
- REASON_UNKNOWN = 0;
- REASON_OTHER = 1;
- REASON_INITIAL = 2;
- REASON_MANUAL = 3;
- REASON_ADAPTIVE = 4;
-}
diff --git a/core/proto/android/stats/otaupdate/updateengine_enums.proto b/core/proto/android/stats/otaupdate/updateengine_enums.proto
deleted file mode 100644
index a6e9919ba606..000000000000
--- a/core/proto/android/stats/otaupdate/updateengine_enums.proto
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.otaupdate;
-
-// The payload type of an OTA update attempt on A/B devices.
-enum PayloadType {
- FULL = 10000;
- DELTA = 10001;
-}
-
-// The attempt result reported by the update engine for an OTA update.
-enum AttemptResult {
- UPDATE_SUCCEEDED = 10000;
- INTERNAL_ERROR = 10001;
- PAYLOAD_DOWNLOAD_ERROR = 10002;
- METADATA_MALFORMED = 10003;
- OPERATION_MALFORMED = 10004;
- OPERATION_EXECUTION_ERROR = 10005;
- METADATA_VERIFICATION_FAILED = 10006;
- PAYLOAD_VERIFICATION_FAILED = 10007;
- VERIFICATION_FAILED = 10008;
- POSTINSTALL_FAILED = 10009;
- ABNORMAL_TERMINATION = 10010;
- UPDATE_CANCELED = 10011;
- UPDATE_SUCCEEDED_NOT_ACTIVE = 10012;
-}
-
-// The error code reported by the update engine after an OTA update attempt
-// on A/B devices. More details in system/update_engine/common/error_code.h
-enum ErrorCode {
- SUCCESS = 10000;
- ERROR = 10001;
- FILESYSTEM_COPIER_ERROR = 10004;
- POST_INSTALL_RUNNER_ERROR = 10005;
- PAYLOAD_MISMATCHED_TYPE_ERROR = 10006;
- INSTALL_DEVICE_OPEN_ERROR = 10007;
- KERNEL_DEVICE_OPEN_ERROR = 10008;
- DOWNLOAD_TRANSFER_ERROR = 10009;
- PAYLOAD_HASH_MISMATCH_ERROR = 10010;
- PAYLOAD_SIZE_MISMATCH_ERROR = 10011;
- DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 10012;
- DOWNLOAD_NEW_PARTITION_INFO_ERROR = 10013;
- DOWNLOAD_WRITE_ERROR = 10014;
- NEW_ROOTFS_VERIFICATION_ERROR = 10015;
- SIGNED_DELTA_PAYLOAD_EXPECTED_ERROR = 10017;
- DOWNLOAD_PAYLOAD_PUB_KEY_VERIFICATION_ERROR = 10018;
- DOWNLOAD_STATE_INITIALIZATION_ERROR = 10020;
- DOWNLOAD_INVALID_METADATA_MAGIC_STRING = 10021;
- DOWNLOAD_SIGNATURE_MISSING_IN_MANIFEST = 10022;
- DOWNLOAD_MANIFEST_PARSE_ERROR = 10023;
- DOWNLOAD_METADATA_SIGNATURE_ERROR = 10024;
- DOWNLOAD_METADATA_SIGNATURE_VERIFICATION_ERROR = 10025;
- DOWNLOAD_METADATA_SIGNATURE_MISMATCH = 10026;
- DOWNLOAD_OPERATION_HASH_VERIFICATION_ERROR = 10027;
- DOWNLOAD_OPERATION_EXECUTION_ERROR = 10028;
- DOWNLOAD_OPERATION_HASH_MISMATCH = 10029;
- DOWNLOAD_INVALID_METADATA_SIZE = 10032;
- DOWNLOAD_INVALID_METADATA_SIGNATURE = 10033;
- DOWNLOAD_OPERATION_HASH_MISSING_ERROR = 10038;
- DOWNLOAD_METADATA_SIGNATURE_MISSING_ERROR = 10039;
- UNSUPPORTED_MAJOR_PAYLOAD_VERSION = 10044;
- UNSUPPORTED_MINOR_PAYLOAD_VERSION = 10045;
- FILESYSTEM_VERIFIER_ERROR = 10047;
- USER_CANCELED = 10048;
- PAYLOAD_TIMESTAMP_ERROR = 10051;
- UPDATED_BUT_NOT_ACTIVE = 10052;
-}
diff --git a/core/proto/android/stats/style/Android.bp b/core/proto/android/stats/style/Android.bp
deleted file mode 100644
index f085a52f8cdb..000000000000
--- a/core/proto/android/stats/style/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "styleprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
-
- sdk_version: "current",
- srcs: [
- "*.proto",
- ],
-}
diff --git a/core/proto/android/stats/style/style_enums.proto b/core/proto/android/stats/style/style_enums.proto
deleted file mode 100644
index 2876882e78ba..000000000000
--- a/core/proto/android/stats/style/style_enums.proto
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.style;
-option java_multiple_files = true;
-
-enum Action {
- DEFAULT_ACTION = 0;
- ONRESUME = 1;
- ONSTOP = 2;
- PICKER_SELECT = 3;
- PICKER_APPLIED = 4;
- WALLPAPER_OPEN_CATEGORY = 5;
- WALLPAPER_SELECT = 6;
- WALLPAPER_APPLIED = 7;
- WALLPAPER_EXPLORE = 8;
- WALLPAPER_DOWNLOAD = 9;
- WALLPAPER_REMOVE = 10;
- LIVE_WALLPAPER_DOWNLOAD_SUCCESS = 11;
- LIVE_WALLPAPER_DOWNLOAD_FAILED = 12;
- LIVE_WALLPAPER_DOWNLOAD_CANCELLED = 13;
- LIVE_WALLPAPER_DELETE_SUCCESS = 14;
- LIVE_WALLPAPER_DELETE_FAILED = 15;
- LIVE_WALLPAPER_APPLIED = 16;
- LIVE_WALLPAPER_INFO_SELECT = 17;
- LIVE_WALLPAPER_CUSTOMIZE_SELECT = 18;
- LIVE_WALLPAPER_QUESTIONNAIRE_SELECT = 19;
- LIVE_WALLPAPER_QUESTIONNAIRE_APPLIED = 20;
- LIVE_WALLPAPER_EFFECT_SHOW = 21;
- APP_LAUNCHED = 22;
-}
-
-enum LocationPreference {
- LOCATION_PREFERENCE_UNSPECIFIED = 0;
- LOCATION_UNAVAILABLE = 1;
- LOCATION_CURRENT = 2;
- LOCATION_MANUAL = 3;
-}
-
-enum DatePreference {
- DATE_PREFERENCE_UNSPECIFIED = 0;
- DATE_UNAVAILABLE = 1;
- DATE_MANUAL = 2;
-}
-
-enum LaunchedPreference {
- LAUNCHED_PREFERENCE_UNSPECIFIED = 0;
- LAUNCHED_LAUNCHER = 1;
- LAUNCHED_SETTINGS = 2;
- LAUNCHED_SUW = 3;
- LAUNCHED_TIPS = 4;
- LAUNCHED_LAUNCH_ICON = 5;
- LAUNCHED_CROP_AND_SET_ACTION = 6;
- LAUNCHED_DEEP_LINK = 7;
-}
diff --git a/core/proto/android/stats/sysui/notification_enums.proto b/core/proto/android/stats/sysui/notification_enums.proto
deleted file mode 100644
index 30bdecae07d1..000000000000
--- a/core/proto/android/stats/sysui/notification_enums.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.sysui;
-
-// Enum used in NotificationReported and NotificationChannelModified atoms
-enum NotificationImportance { // Constants from NotificationManager.java
- IMPORTANCE_UNSPECIFIED = -1000; // Should not occur for real notifications.
- IMPORTANCE_NONE = 0; // No importance: does not show in the shade.
- IMPORTANCE_MIN = 1; // Minimum to show in the shade.
- IMPORTANCE_LOW = 2; // Shows in shade, maybe status bar, no buzz/beep.
- IMPORTANCE_DEFAULT = 3; // Shows everywhere, makes noise, no heads-up.
- IMPORTANCE_HIGH = 4; // Shows everywhere, makes noise, heads-up, may full-screen.
- IMPORTANCE_IMPORTANT_CONVERSATION = 5; // High + isImportantConversation().
-}
diff --git a/core/proto/android/stats/textclassifier/Android.bp b/core/proto/android/stats/textclassifier/Android.bp
deleted file mode 100644
index bf9022711206..000000000000
--- a/core/proto/android/stats/textclassifier/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_static {
- name: "textclassifierprotoslite",
- proto: {
- type: "lite",
- },
- srcs: [
- "*.proto",
- ],
-} \ No newline at end of file
diff --git a/core/proto/android/stats/textclassifier/textclassifier_enums.proto b/core/proto/android/stats/textclassifier/textclassifier_enums.proto
deleted file mode 100644
index 4be7b7c2df7c..000000000000
--- a/core/proto/android/stats/textclassifier/textclassifier_enums.proto
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.stats.textclassifier;
-option java_multiple_files = true;
-
-enum EventType {
- TYPE_UNKNOWN = 0;
- // User started a new selection.
- SELECTION_STARTED = 1;
- // User modified an existing selection.
- SELECTION_MODIFIED = 2;
- // Smart selection triggered for a single token (word).
- SMART_SELECTION_SINGLE = 3;
- // Smart selection triggered spanning multiple tokens (words).
- SMART_SELECTION_MULTI = 4;
- // Something else other than user or the default TextClassifier triggered a selection.
- AUTO_SELECTION = 5;
- // Smart actions shown to the user.
- ACTIONS_SHOWN = 6;
- // User clicked a link.
- LINK_CLICKED = 7;
- // User typed over the selection.
- OVERTYPE = 8;
- // User clicked on Copy action.
- COPY_ACTION = 9;
- // User clicked on Paste action.
- PASTE_ACTION = 10;
- // User clicked on Cut action.
- CUT_ACTION = 11;
- // User clicked on Share action.
- SHARE_ACTION = 12;
- // User clicked on a Smart action.
- SMART_ACTION = 13;
- // User dragged+dropped the selection.
- SELECTION_DRAG = 14;
- // Selection is destroyed.
- SELECTION_DESTROYED = 15;
- // User clicked on a custom action.
- OTHER_ACTION = 16;
- // User clicked on Select All action
- SELECT_ALL = 17;
- // User reset the smart selection.
- SELECTION_RESET = 18;
- // User composed a reply.
- MANUAL_REPLY = 19;
- // TextClassifier generated some actions
- ACTIONS_GENERATED = 20;
- // Some text links were generated
- LINKS_GENERATED = 21;
-}
-
-enum WidgetType {
- WIDGET_TYPE_UNKNOWN = 0;
- // Standard TextView
- WIDGET_TYPE_TEXTVIEW = 1;
- // EditText
- WIDGET_TYPE_EDITTEXT = 2;
- // Not selectable textview
- WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = 3;
- // Standard Webview
- WIDGET_TYPE_WEBVIEW = 4;
- // Editable TextView
- WIDGET_TYPE_EDIT_WEBVIEW = 5;
- // Custom text widget
- WIDGET_TYPE_CUSTOM_TEXTVIEW = 6;
- // Custom editable text widget.
- WIDGET_TYPE_CUSTOM_EDITTEXT = 7;
- // Non-selectable text widget.
- WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = 8;
- // Notification
- WIDGET_TYPE_NOTIFICATION = 9;
-}
diff --git a/core/proto/android/stats/tls/enums.proto b/core/proto/android/stats/tls/enums.proto
deleted file mode 100644
index a64137d7caa9..000000000000
--- a/core/proto/android/stats/tls/enums.proto
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-syntax = "proto2";
-package android.stats.tls;
-
-// Keep in sync with
-// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java
-enum Protocol {
- UNKNOWN_PROTO = 0;
- SSL_V3 = 1;
- TLS_V1 = 2;
- TLS_V1_1 = 3;
- TLS_V1_2 = 4;
- TLS_V1_3 = 5;
-}
-
-// Cipher suites' ids are based on IANA's database:
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
-//
-// If you add new cipher suite, make sure id is the same as in IANA's database (see link above)
-//
-// Keep in sync with
-// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java
-enum CipherSuite {
- UNKNOWN_CIPHER_SUITE = 0x0000;
-
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
- TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035;
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009;
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013;
- TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F;
- TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A;
-
- // TLSv1.2 cipher suites
- TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C;
- TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D;
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F;
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030;
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B;
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C;
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9;
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8;
-
- // Pre-Shared Key (PSK) cipher suites
- TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C;
- TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D;
- TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035;
- TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036;
- TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC;
-
- // TLS 1.3 cipher suites
- TLS_AES_128_GCM_SHA256 = 0x1301;
- TLS_AES_256_GCM_SHA384 = 0x1302;
- TLS_CHACHA20_POLY1305_SHA256 = 0x1303;
-}
-
diff --git a/core/proto/android/stats/tv/tif_enums.proto b/core/proto/android/stats/tv/tif_enums.proto
deleted file mode 100644
index a9028e529186..000000000000
--- a/core/proto/android/stats/tv/tif_enums.proto
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-
-package android.stats.tv;
-option java_multiple_files = true;
-
-// Enums for TV Input Framework
-option java_outer_classname = "TifStatsEnums";
-
-// Tune State of a TV Input Service Framework
-enum TifTuneState {
- TIF_TUNE_STATE_UNKNOWN = 0;
- CREATED = 1;
- SURFACE_ATTACHED = 2;
- SURFACE_DETACHED = 3;
- RELEASED = 4;
- TUNE_STARTED = 5;
- VIDEO_AVAILABLE = 6;
-
- // Keep in sync with TvInputManager
- // Use the TvInputManager value + 100
- VIDEO_UNAVAILABLE_REASON_UNKNOWN = 100;
- VIDEO_UNAVAILABLE_REASON_TUNING = 101;
- VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 102;
- VIDEO_UNAVAILABLE_REASON_BUFFERING = 103;
- VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 104;
- VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 105;
- VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 106;
- VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION=107;
- VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED=108;
- VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE=109;
- VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED=110;
- VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION=111;
- VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING=112;
- VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD=113;
- VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE=114;
- VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID=115;
- VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT=116;
- VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING=117;
- VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN=118;
-}
diff --git a/core/proto/android/telecomm/enums.proto b/core/proto/android/telecomm/enums.proto
deleted file mode 100644
index 5ca4a85f7c6a..000000000000
--- a/core/proto/android/telecomm/enums.proto
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.telecom;
-
-option java_outer_classname = "TelecomProtoEnums";
-option java_multiple_files = true;
-
-/**
- * Call states, primarily used in CallState.java,
- * Call.java, and CallsManager.java in packages/services.
- */
-enum CallStateEnum {
- /**
- * Indicates that a call is new and not connected. This is used as the default state internally
- * within Telecom and should not be used between Telecom and call services. Call services are
- * not expected to ever interact with NEW calls, but {@link android.telecom.InCallService}s will
- * see calls in this state.
- */
- NEW = 0;
-
- /**
- * The initial state of an outgoing {@code Call}.
- * Common transitions are to {@link #DIALING} state for a successful call or
- * {@link #DISCONNECTED} if it failed.
- */
- CONNECTING = 1;
-
- /**
- * The state of an outgoing {@code Call} when waiting on user to select a
- * {@link android.telecom.PhoneAccount} through which to place the call.
- */
- SELECT_PHONE_ACCOUNT = 2;
-
- /**
- * Indicates that a call is outgoing and in the dialing state. A call transitions to this state
- * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this
- * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED}
- * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user).
- */
- DIALING = 3;
-
- /**
- * Indicates that a call is incoming and the user still has the option of answering, rejecting,
- * or doing nothing with the call. This state is usually associated with some type of audible
- * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED}
- * otherwise.
- */
- RINGING = 4;
-
- /**
- * Indicates that a call is currently connected to another party and a communication channel is
- * open between them. The normal transition to this state is by the user answering a
- * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party.
- */
- ACTIVE = 5;
-
- /**
- * Indicates that the call is currently on hold. In this state, the call is not terminated
- * but no communication is allowed until the call is no longer on hold. The typical transition
- * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing
- * an action, such as clicking the hold button.
- */
- ON_HOLD = 6;
-
- /**
- * Indicates that a call is currently disconnected. All states can transition to this state
- * by the call service giving notice that the connection has been severed. When the user
- * explicitly ends a call, it will not transition to this state until the call service confirms
- * the disconnection or communication was lost to the call service currently responsible for
- * this call (e.g., call service crashes).
- */
- DISCONNECTED = 7;
-
- /**
- * Indicates that the call was attempted (mostly in the context of outgoing, at least at the
- * time of writing) but cancelled before it was successfully connected.
- */
- ABORTED = 8;
-
- /**
- * Indicates that the call is in the process of being disconnected and will transition next
- * to a {@link #DISCONNECTED} state.
- * <p>
- * This state is not expected to be communicated from the Telephony layer, but will be reported
- * to the InCall UI for calls where disconnection has been initiated by the user but the
- * ConnectionService has confirmed the call as disconnected.
- */
- DISCONNECTING = 9;
-
- /**
- * Indicates that the call is in the process of being pulled to the local device.
- * <p>
- * This state should only be set on a call with
- * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL} and
- * {@link android.telecom.Connection#CAPABILITY_CAN_PULL_CALL}.
- */
- PULLING = 10;
-
- /**
- * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet
- * set the call to active.
- */
- ANSWERED = 11;
-
- /**
- * Indicates that the call is undergoing audio processing by a different app in the background.
- * @see android.telecom.Call#STATE_AUDIO_PROCESSING
- */
- AUDIO_PROCESSING = 12;
-
- /**
- * Indicates that the call is in a fake ringing state.
- * @see android.telecom.Call#STATE_SIMULATED_RINGING
- */
- SIMULATED_RINGING = 13;
-}
-
-// Disconnect causes for a call. Primarily used by android/telecom/DisconnectCause.java
-enum DisconnectCauseEnum {
- /**
- * Disconnected because of an unknown or unspecified reason.
- */
- UNKNOWN = 0;
-
- /**
- * Disconnected because there was an error, such as a problem with the network.
- */
- ERROR = 1;
-
- /**
- * Disconnected because of a local user-initiated action, such as hanging up.
- */
- LOCAL = 2;
-
- /**
- * Disconnected because of a remote user-initiated action, such as the other party hanging up
- * up.
- */
- REMOTE = 3;
-
- /**
- * Disconnected because it has been canceled.
- */
- CANCELED = 4;
-
- /**
- * Disconnected because there was no response to an incoming call.
- */
- MISSED = 5;
-
- /**
- * Disconnected because the user rejected an incoming call.
- */
- REJECTED = 6;
-
- /**
- * Disconnected because the other party was busy.
- */
- BUSY = 7;
-
- /**
- * Disconnected because of a restriction on placing the call, such as dialing in airplane
- * mode.
- */
- RESTRICTED = 8;
-
- /**
- * Disconnected for reason not described by other disconnect codes.
- */
- OTHER = 9;
-
- /**
- * Disconnected because the connection manager did not support the call. The call will be tried
- * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
- */
- CONNECTION_MANAGER_NOT_SUPPORTED = 10;
-
- /**
- * Disconnected because the user did not locally answer the incoming call, but it was answered
- * on another device where the call was ringing.
- */
- ANSWERED_ELSEWHERE = 11;
-
- /**
- * Disconnected because the call was pulled from the current device to another device.
- */
- CALL_PULLED = 12;
-}
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
deleted file mode 100644
index b435fe7d9784..000000000000
--- a/core/proto/android/telephony/enums.proto
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.telephony;
-
-option java_outer_classname = "TelephonyProtoEnums";
-option java_multiple_files = true;
-
-enum CallBearerEnum {
- /** Call bearer is unknown or invalid */
- CALL_BEARER_UNKNOWN = 0;
-
- /** Call bearer is legacy CS */
- CALL_BEARER_CS = 1;
-
- /** Call bearer is IMS */
- CALL_BEARER_IMS = 2;
-}
-
-enum CallDirectionEnum {
- /** Call direction: unknown or invalid */
- CALL_DIRECTION_UNKNOWN = 0;
-
- /** Call direction: mobile originated (outgoing for this device) */
- CALL_DIRECTION_MO = 1;
-
- /** Call direction: mobile terminated (incoming for this device) */
- CALL_DIRECTION_MT = 2;
-}
-
-// Call setup duration buckets.
-// See com.android.internal.telephony.metrics.VoiceCallSessionStats for definition.
-enum CallSetupDurationEnum {
- CALL_SETUP_DURATION_UNKNOWN = 0;
- CALL_SETUP_DURATION_EXTREMELY_FAST = 1;
- CALL_SETUP_DURATION_ULTRA_FAST = 2;
- CALL_SETUP_DURATION_VERY_FAST = 3;
- CALL_SETUP_DURATION_FAST = 4;
- CALL_SETUP_DURATION_NORMAL = 5;
- CALL_SETUP_DURATION_SLOW = 6;
- CALL_SETUP_DURATION_VERY_SLOW = 7;
- CALL_SETUP_DURATION_ULTRA_SLOW = 8;
- CALL_SETUP_DURATION_EXTREMELY_SLOW = 9;
-}
-
-// Data conn. power states, primarily used by android/telephony/DataConnectionRealTimeInfo.java.
-enum DataConnectionPowerStateEnum {
- DATA_CONNECTION_POWER_STATE_LOW = 1;
- DATA_CONNECTION_POWER_STATE_MEDIUM = 2;
- DATA_CONNECTION_POWER_STATE_HIGH = 3;
- DATA_CONNECTION_POWER_STATE_UNKNOWN = 2147483647; // Java Integer.MAX_VALUE;
-}
-
-// Network type enums, primarily used by android/telephony/TelephonyManager.java.
-// Do not add negative types.
-enum NetworkTypeEnum {
- NETWORK_TYPE_UNKNOWN = 0;
- NETWORK_TYPE_GPRS = 1;
- NETWORK_TYPE_EDGE = 2;
- NETWORK_TYPE_UMTS = 3;
- NETWORK_TYPE_CDMA = 4;
- NETWORK_TYPE_EVDO_0 = 5;
- NETWORK_TYPE_EVDO_A = 6;
- NETWORK_TYPE_1XRTT = 7;
- NETWORK_TYPE_HSDPA = 8;
- NETWORK_TYPE_HSUPA = 9;
- NETWORK_TYPE_HSPA = 10;
- NETWORK_TYPE_IDEN = 11;
- NETWORK_TYPE_EVDO_B = 12;
- NETWORK_TYPE_LTE = 13;
- NETWORK_TYPE_EHRPD = 14;
- NETWORK_TYPE_HSPAP = 15;
- NETWORK_TYPE_GSM = 16;
- NETWORK_TYPE_TD_SCDMA = 17;
- NETWORK_TYPE_IWLAN = 18;
- NETWORK_TYPE_LTE_CA = 19;
- NETWORK_TYPE_NR = 20;
-}
-
-// Roaming type enums, see android.telephony.ServiceState.RoamingType for definitions.
-enum RoamingTypeEnum {
- ROAMING_TYPE_NOT_ROAMING = 0;
- ROAMING_TYPE_ROAMING = 1;
- ROAMING_TYPE_ROAMING_DOMESTIC = 2;
- ROAMING_TYPE_ROAMING_INTERNATIONAL = 3;
-}
-
-// Signal strength levels, as defined in android/telephony/SignalStrength.java.
-enum SignalStrengthEnum {
- SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- SIGNAL_STRENGTH_POOR = 1;
- SIGNAL_STRENGTH_MODERATE = 2;
- SIGNAL_STRENGTH_GOOD = 3;
- SIGNAL_STRENGTH_GREAT = 4;
-}
-
-enum ServiceStateEnum {
- /**
- * Normal operation condition, the phone is registered
- * with an operator either in home network or in roaming.
- */
- SERVICE_STATE_IN_SERVICE = 0;
-
- /**
- * Phone is not registered with any operator, the phone
- * can be currently searching a new operator to register to, or not
- * searching to registration at all, or registration is denied, or radio
- * signal is not available.
- */
- SERVICE_STATE_OUT_OF_SERVICE = 1;
-
- /**
- * The phone is registered and locked. Only emergency numbers are allowed. {@more}
- */
- SERVICE_STATE_EMERGENCY_ONLY = 2;
-
- /**
- * Radio of telephony is explicitly powered off.
- */
- SERVICE_STATE_POWER_OFF = 3;
-}
-
-enum SimStateEnum {
- SIM_STATE_UNKNOWN = 0;
- /** SIM card state: no SIM card is available in the device */
- SIM_STATE_ABSENT = 1;
- /** SIM card state: Locked: requires the user's SIM PIN to unlock */
- SIM_STATE_PIN_REQUIRED = 2;
- /** SIM card state: Locked: requires the user's SIM PUK to unlock */
- SIM_STATE_PUK_REQUIRED = 3;
- /** SIM card state: Locked: requires a network PIN to unlock */
- SIM_STATE_NETWORK_LOCKED = 4;
- /** SIM card state: Ready */
- SIM_STATE_READY = 5;
- /** SIM card state: SIM Card is NOT READY */
- SIM_STATE_NOT_READY = 6;
- /** SIM card state: SIM Card Error, permanently disabled */
- SIM_STATE_PERM_DISABLED = 7;
- /** SIM card state: SIM Card Error, present but faulty */
- SIM_STATE_CARD_IO_ERROR = 8;
- /** SIM card state: SIM Card restricted, present but not usable due to
- * carrier restrictions.
- */
- SIM_STATE_CARD_RESTRICTED = 9;
- /**
- * SIM card state: Loaded: SIM card applications have been loaded
- * @hide
- */
- SIM_STATE_LOADED = 10;
- /**
- * SIM card state: SIM Card is present
- * @hide
- */
- SIM_STATE_PRESENT = 11;
-}
-
-// Format of SMS message
-enum SmsFormatEnum {
- /** Unknown format */
- SMS_FORMAT_UNKNOWN = 0;
- /** Format compliant with 3GPP TS 23.040 */
- SMS_FORMAT_3GPP = 1;
- /** Format compliant with 3GPP2 TS C.S0015-B */
- SMS_FORMAT_3GPP2 = 2;
-}
-
-// Technology used to carry an SMS message
-enum SmsTechEnum {
- /**
- * Unknown SMS technology used to carry the SMS.
- * This value is also used for injected SMS.
- */
- SMS_TECH_UNKNOWN = 0;
- /** The SMS was carried over CS bearer in 3GPP network */
- SMS_TECH_CS_3GPP = 1;
- /** The SMS was carried over CS bearer in 3GPP2 network */
- SMS_TECH_CS_3GPP2 = 2;
- /** The SMS was carried over IMS */
- SMS_TECH_IMS = 3;
-}
-
-// Types of SMS message
-enum SmsTypeEnum {
- /** Normal type. */
- SMS_TYPE_NORMAL = 0;
- /** SMS-PP (point-to-point). */
- SMS_TYPE_SMS_PP = 1;
- /** Voicemail indication. */
- SMS_TYPE_VOICEMAIL_INDICATION = 2;
- /** Type 0 message (3GPP TS 23.040 9.2.3.9). */
- SMS_TYPE_ZERO = 3;
- /** WAP-PUSH message. */
- SMS_TYPE_WAP_PUSH = 4;
-}
-
-// Incoming SMS errors
-enum SmsIncomingErrorEnum {
- SMS_SUCCESS = 0;
- SMS_ERROR_GENERIC = 1;
- SMS_ERROR_NO_MEMORY = 2;
- SMS_ERROR_NOT_SUPPORTED = 3;
-}
-
-// Outgoing SMS results
-enum SmsSendResultEnum {
- // Unknown error
- SMS_SEND_RESULT_UNKNOWN = 0;
- // Success
- SMS_SEND_RESULT_SUCCESS = 1;
- // Permanent error
- SMS_SEND_RESULT_ERROR = 2;
- // Temporary error, retry
- SMS_SEND_RESULT_ERROR_RETRY = 3;
- // Error over IMS, retry on CS
- SMS_SEND_RESULT_ERROR_FALLBACK = 4;
-}
-
-// Data profile of the data call. From
-// frameworks/base/telephony/java/com/android/internal/telephony/RILConstants.java
-enum DataProfileEnum {
- DATA_PROFILE_DEFAULT = 0;
- DATA_PROFILE_TETHERED = 1;
- DATA_PROFILE_IMS = 2;
- DATA_PROFILE_FOTA = 3;
- DATA_PROFILE_CBS = 4;
- DATA_PROFILE_OEM_BASE = 1000;
- DATA_PROFILE_INVALID = -1;
-}
-
-// Reason of data call deactivation. From
-// frameworks/base/telephony/java/android/telephony/data/DataService.java#DeactivateDataReason
-enum DataDeactivateReasonEnum {
- DEACTIVATE_REASON_UNKNOWN = 0;
- DEACTIVATE_REASON_NORMAL = 1;
- DEACTIVATE_REASON_RADIO_OFF = 2;
- DEACTIVATE_REASON_HANDOVER = 3;
-}
-
-// IP type of the data call
-// see frameworks/base/telephony/java/android/telephony/data/ApnSetting.java#ProtocolType
-enum ApnProtocolEnum {
- APN_PROTOCOL_IPV4 = 0;
- APN_PROTOCOL_IPV6 = 1;
- APN_PROTOCOL_IPV4V6 = 2;
- APN_PROTOCOL_PPP = 3;
-}
-
-// Action taken to recover a data call that is stalled. From
-// frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
-// #RecoveryAction
-enum DataStallRecoveryActionEnum {
- RECOVERY_ACTION_GET_DATA_CALL_LIST = 0;
- RECOVERY_ACTION_CLEANUP = 1;
- RECOVERY_ACTION_REREGISTER = 2;
- RECOVERY_ACTION_RADIO_RESTART = 3;
-}
-
-// Codec quality
-enum CodecQuality {
- /** Codec quality: unknown */
- CODEC_QUALITY_UNKNOWN = 0;
-
- /** Codec quality: narrowband */
- CODEC_QUALITY_NARROWBAND = 1;
-
- /** Codec quality: wideband */
- CODEC_QUALITY_WIDEBAND = 2;
-
- /** Codec quality: super-wideband */
- CODEC_QUALITY_SUPER_WIDEBAND = 3;
-
- /** Codec quality: fullband */
- CODEC_QUALITY_FULLBAND = 4;
-}
diff --git a/core/proto/android/view/enums.proto b/core/proto/android/view/enums.proto
deleted file mode 100644
index a601abee17f6..000000000000
--- a/core/proto/android/view/enums.proto
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.view;
-
-option java_outer_classname = "ViewProtoEnums";
-option java_multiple_files = true;
-
-// Screen states, primarily used by android/view/Display.java.
-enum DisplayStateEnum {
- // The display state is unknown.
- DISPLAY_STATE_UNKNOWN = 0;
- // The display state is off.
- DISPLAY_STATE_OFF = 1;
- // The display state is on.
- DISPLAY_STATE_ON = 2;
- // The display is dozing in a low power state; it is still on but is
- // optimized for showing system-provided content while the device is
- // non-interactive.
- DISPLAY_STATE_DOZE = 3;
- // The display is dozing in a suspended low power state; it is still on
- // but is optimized for showing static system-provided content while the
- // device is non-interactive.
- DISPLAY_STATE_DOZE_SUSPEND = 4;
- // The display is on and optimized for VR mode.
- DISPLAY_STATE_VR = 5;
- // The display is in a suspended full power state; it is still on but the
- // CPU is not updating it.
- DISPLAY_STATE_ON_SUSPEND = 6;
-}
-
-// Constants found in android.view.WindowManager.
-enum TransitionTypeEnum {
- TRANSIT_NONE = 0;
- TRANSIT_UNSET = -1;
- TRANSIT_ACTIVITY_OPEN = 6;
- TRANSIT_ACTIVITY_CLOSE = 7;
- TRANSIT_TASK_OPEN = 8;
- TRANSIT_TASK_CLOSE = 9;
- TRANSIT_TASK_TO_FRONT = 10;
- TRANSIT_TASK_TO_BACK = 11;
- TRANSIT_WALLPAPER_CLOSE = 12;
- TRANSIT_WALLPAPER_OPEN = 13;
- TRANSIT_WALLPAPER_INTRA_OPEN = 14;
- TRANSIT_WALLPAPER_INTRA_CLOSE = 15;
- TRANSIT_TASK_OPEN_BEHIND = 16;
- TRANSIT_TASK_IN_PLACE = 17;
- TRANSIT_ACTIVITY_RELAUNCH = 18;
- TRANSIT_DOCK_TASK_FROM_RECENTS = 19 [deprecated=true];
- TRANSIT_KEYGUARD_GOING_AWAY = 20;
- TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
- TRANSIT_KEYGUARD_OCCLUDE = 22;
- TRANSIT_KEYGUARD_UNOCCLUDE = 23;
- TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = 24;
- TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
- TRANSIT_CRASHING_ACTIVITY_CLOSE = 26;
-}
diff --git a/core/proto/android/bluetooth/a2dp/enums.proto b/core/proto/android/view/inputmethod/inputconnection.proto
index 5a025bdd6c10..ad9a95aa95e6 100644
--- a/core/proto/android/bluetooth/a2dp/enums.proto
+++ b/core/proto/android/view/inputmethod/inputconnection.proto
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,20 @@
*/
syntax = "proto2";
-package android.bluetooth.a2dp;
-option java_outer_classname = "BluetoothA2dpProtoEnums";
-option java_multiple_files = true;
+import "frameworks/base/core/proto/android/privacy.proto";
+
+package android.view.inputmethod;
-// A2dp playback state enum, defined from:
-// frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java
-enum PlaybackStateEnum {
- PLAYBACK_STATE_UNKNOWN = 0;
- PLAYBACK_STATE_PLAYING = 10;
- PLAYBACK_STATE_NOT_PLAYING = 11;
-}
+option java_multiple_files = true;
-enum AudioCodingModeEnum {
- AUDIO_CODING_MODE_UNKNOWN = 0;
- AUDIO_CODING_MODE_HARDWARE = 1;
- AUDIO_CODING_MODE_SOFTWARE = 2;
-}
+/**
+ * Represents a {@link android.view.inputmethod.InputConnection} object.
+ */
+message InputConnectionProto {
+ optional string editable_text = 1 [(.android.privacy).dest = DEST_LOCAL];
+ optional string selected_text = 2 [(.android.privacy).dest = DEST_LOCAL];
+ optional int32 selected_text_start = 3;
+ optional int32 selected_text_end = 4;
+ optional int32 cursor_caps_mode = 5;
+} \ No newline at end of file
diff --git a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto
index 5c0f341cb9e4..c1dce6f2d093 100644
--- a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto
+++ b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto
@@ -24,6 +24,7 @@ import "frameworks/base/core/proto/android/view/viewrootimpl.proto";
import "frameworks/base/core/proto/android/view/insetscontroller.proto";
import "frameworks/base/core/proto/android/view/imeinsetssourceconsumer.proto";
import "frameworks/base/core/proto/android/view/inputmethod/editorinfo.proto";
+import "frameworks/base/core/proto/android/view/inputmethod/inputconnection.proto";
import "frameworks/base/core/proto/android/view/imefocuscontroller.proto";
import "frameworks/base/core/proto/android/server/inputmethod/inputmethodmanagerservice.proto";
@@ -70,6 +71,7 @@ message InputMethodClientsTraceProto {
optional ImeInsetsSourceConsumerProto ime_insets_source_consumer = 5;
optional EditorInfoProto editor_info = 6;
optional ImeFocusControllerProto ime_focus_controller = 7;
+ optional InputConnectionProto input_connection = 8;
}
}
diff --git a/core/proto/android/wifi/enums.proto b/core/proto/android/wifi/enums.proto
deleted file mode 100644
index e676fef8c2e0..000000000000
--- a/core/proto/android/wifi/enums.proto
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.net.wifi;
-
-option java_outer_classname = "WifiProtoEnums";
-option java_multiple_files = true;
-
-/**
- * Wifi Lock modes, primarily used in
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiLockManager.java.
- */
-enum WifiModeEnum {
- /**
- * Deprecated.
- * Wi-Fi will be kept active, and will behave normally.
- */
- WIFI_MODE_FULL = 1 [deprecated=true];
-
- /**
- * Deprecated.
- * Wi-Fi will be kept active, but the only operation that will be supported is initiation of
- * scans, and the subsequent reporting of scan results.
- */
- WIFI_MODE_SCAN_ONLY = 2 [deprecated=true];
-
- /**
- * Wi-Fi will not go to power save.
- */
- WIFI_MODE_FULL_HIGH_PERF = 3;
-
- /**
- * Wi-Fi will operate with a priority to achieve low latency.
- */
- WIFI_MODE_FULL_LOW_LATENCY = 4;
-}
-
-/**
- * Wifi authentication type.
- */
-enum WifiAuthType {
- AUTH_TYPE_NONE = 0;
-
- // WPA pre-shared key.
- AUTH_TYPE_WPA_PSK = 1;
- // WPA using EAP authentication. Generally used with an external authentication server.
- AUTH_TYPE_WPA_EAP = 2;
- // IEEE 802.1X using EAP authentication and (optionally) dynamically generated WEP keys.
- AUTH_TYPE_IEEE8021X = 3;
- // WPA2 pre-shared key for use with soft access point.
- AUTH_TYPE_WPA2_PSK = 4;
- // Hotspot 2.0 r2 OSEN.
- AUTH_TYPE_OSEN = 5;
- // IEEE 802.11r Fast BSS Transition with PSK authentication.
- AUTH_TYPE_FT_PSK = 6;
- // IEEE 802.11r Fast BSS Transition with EAP authentication.
- AUTH_TYPE_FT_EAP = 7;
- // Simultaneous Authentication of Equals.
- AUTH_TYPE_SAE = 8;
- // Opportunistic Wireless Encryption.
- AUTH_TYPE_OWE = 9;
- // SUITE_B_192 192 bit level
- AUTH_TYPE_SUITE_B_192 = 10;
- // WPA pre-shared key with stronger SHA256-based algorithms.
- AUTH_TYPE_WPA_PSK_SHA256 = 11;
- // WPA using EAP authentication with stronger SHA256-based algorithms.
- AUTH_TYPE_WPA_EAP_SHA256 = 12;
- // WAPI pre-shared key.
- AUTH_TYPE_WAPI_PSK = 13;
- // WAPI certificate to be specified.
- AUTH_TYPE_WAPI_CERT = 14;
- // IEEE 802.11ai FILS SK with SHA256.
- AUTH_TYPE_FILS_SHA256 = 15;
- // IEEE 802.11ai FILS SK with SHA384.
- AUTH_TYPE_FILS_SHA384 = 16;
-}
-
-/**
- * Bucketed wifi band.
- */
-enum WifiBandBucket {
- BAND_UNKNOWN = 0;
-
- // All of 2.4GHz band
- BAND_2G = 1;
- // Frequencies in the range of [5150, 5250) GHz
- BAND_5G_LOW = 2;
- // Frequencies in the range of [5250, 5725) GHz
- BAND_5G_MIDDLE = 3;
- // Frequencies in the range of [5725, 5850) GHz
- BAND_5G_HIGH = 4;
- // Frequencies in the range of [5925, 6425) GHz
- BAND_6G_LOW = 5;
- // Frequencies in the range of [6425, 6875) GHz
- BAND_6G_MIDDLE = 6;
- // Frequencies in the range of [6875, 7125) GHz
- BAND_6G_HIGH = 7;
-} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/app/ApplicationLoadersTest.java b/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
index 4b9910c79770..19e7f80dfa5b 100644
--- a/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
@@ -42,7 +42,7 @@ public class ApplicationLoadersTest {
return new SharedLibraryInfo(
zip, null /*packageName*/, null /*codePaths*/, null /*name*/, 0 /*version*/,
SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
- null /*dependentPackages*/, null /*dependencies*/);
+ null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/);
}
@Test
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 4fe68cd5a27a..e5da41c7c113 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -51,6 +51,8 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.os.Bundle;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
@@ -66,6 +68,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.content.ReferrerIntent;
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -95,6 +98,16 @@ public class ActivityThreadTest {
new ActivityTestRule<>(TestActivity.class, true /* initialTouchMode */,
false /* launchActivity */);
+ private ArrayList<VirtualDisplay> mCreatedVirtualDisplays;
+
+ @After
+ public void tearDown() {
+ if (mCreatedVirtualDisplays != null) {
+ mCreatedVirtualDisplays.forEach(VirtualDisplay::release);
+ mCreatedVirtualDisplays = null;
+ }
+ }
+
@Test
public void testDoubleRelaunch() throws Exception {
final Activity activity = mActivityTestRule.launchActivity(new Intent());
@@ -410,7 +423,6 @@ public class ActivityThreadTest {
Context appContext = activity.getApplication();
Configuration originalAppConfig =
new Configuration(appContext.getResources().getConfiguration());
- DisplayManager dm = appContext.getSystemService(DisplayManager.class);
int virtualDisplayWidth;
int virtualDisplayHeight;
@@ -421,8 +433,8 @@ public class ActivityThreadTest {
virtualDisplayWidth = 200;
virtualDisplayHeight = 100;
}
- Display virtualDisplay = dm.createVirtualDisplay("virtual-display",
- virtualDisplayWidth, virtualDisplayHeight, 200, null, 0).getDisplay();
+ final Display virtualDisplay = createVirtualDisplay(appContext,
+ virtualDisplayWidth, virtualDisplayHeight);
Context virtualDisplayContext = appContext.createDisplayContext(virtualDisplay);
int originalVirtualDisplayOrientation = virtualDisplayContext.getResources()
.getConfiguration().orientation;
@@ -467,7 +479,6 @@ public class ActivityThreadTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
Configuration originalActivityConfig =
new Configuration(activity.getResources().getConfiguration());
- DisplayManager dm = activity.getSystemService(DisplayManager.class);
int virtualDisplayWidth;
int virtualDisplayHeight;
@@ -478,8 +489,8 @@ public class ActivityThreadTest {
virtualDisplayWidth = 200;
virtualDisplayHeight = 100;
}
- Display virtualDisplay = dm.createVirtualDisplay("virtual-display",
- virtualDisplayWidth, virtualDisplayHeight, 200, null, 0).getDisplay();
+ final Display virtualDisplay = createVirtualDisplay(activity,
+ virtualDisplayWidth, virtualDisplayHeight);
Context virtualDisplayContext = activity.createDisplayContext(virtualDisplay);
int originalVirtualDisplayOrientation = virtualDisplayContext.getResources()
.getConfiguration().orientation;
@@ -704,6 +715,17 @@ public class ActivityThreadTest {
return config.seq;
}
+ private Display createVirtualDisplay(Context context, int w, int h) {
+ final DisplayManager dm = context.getSystemService(DisplayManager.class);
+ final VirtualDisplay virtualDisplay = dm.createVirtualDisplay("virtual-display", w, h,
+ 200 /* densityDpi */, null /* surface */, 0 /* flags */);
+ if (mCreatedVirtualDisplays == null) {
+ mCreatedVirtualDisplays = new ArrayList<>();
+ }
+ mCreatedVirtualDisplays.add(virtualDisplay);
+ return virtualDisplay.getDisplay();
+ }
+
private static ActivityClientRecord getActivityClientRecord(Activity activity) {
final ActivityThread thread = activity.getActivityThread();
final IBinder token = activity.getActivityToken();
@@ -796,6 +818,14 @@ public class ActivityThreadTest {
volatile CountDownLatch mConfigLatch;
@Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().getDecorView().setKeepScreenOn(true);
+ setShowWhenLocked(true);
+ setTurnScreenOn(true);
+ }
+
+ @Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
mConfig.setTo(config);
diff --git a/core/tests/coretests/src/android/security/CredentialManagementAppTest.java b/core/tests/coretests/src/android/security/CredentialManagementAppTest.java
new file mode 100644
index 000000000000..366aabd183e3
--- /dev/null
+++ b/core/tests/coretests/src/android/security/CredentialManagementAppTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import android.net.Uri;
+import android.util.Xml;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+import java.util.Map;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class CredentialManagementAppTest {
+
+ private static final String TEST_PACKAGE_NAME_1 = "com.android.test";
+ private static final String TEST_PACKAGE_NAME_2 = "com.android.test2";
+ private static final Uri TEST_URI_1 = Uri.parse("test.com");
+ private static final Uri TEST_URI_2 = Uri.parse("test2.com");
+ private static final String TEST_ALIAS_1 = "testAlias";
+ private static final String TEST_ALIAS_2 = "testAlias2";
+
+ private static final String PACKAGE_NAME = "com.android.cred.mng.pkg";
+ private static final AppUriAuthenticationPolicy AUTHENTICATION_POLICY =
+ new AppUriAuthenticationPolicy.Builder()
+ .addAppAndUriMapping(TEST_PACKAGE_NAME_1, TEST_URI_1, TEST_ALIAS_1)
+ .build();
+ private static final CredentialManagementApp CREDENTIAL_MANAGEMENT_APP =
+ new CredentialManagementApp(PACKAGE_NAME, AUTHENTICATION_POLICY);
+
+ private static final String TAG_CREDENTIAL_MANAGEMENT_APP = "credential-management-app";
+
+ @Test
+ public void credentialManagementApp_getters() {
+ CredentialManagementApp credentialManagementApp =
+ new CredentialManagementApp(PACKAGE_NAME, AUTHENTICATION_POLICY);
+
+ assertThat(credentialManagementApp.getPackageName(), is(PACKAGE_NAME));
+ assertThat(credentialManagementApp.getAuthenticationPolicy(), is(AUTHENTICATION_POLICY));
+ }
+
+ @Test
+ public void setAuthenticationPolicy_updatesAuthenticationPolicy() {
+ CredentialManagementApp credentialManagementApp =
+ new CredentialManagementApp(PACKAGE_NAME, AUTHENTICATION_POLICY);
+ AppUriAuthenticationPolicy updatedAuthenticationPolicy =
+ new AppUriAuthenticationPolicy.Builder().addAppAndUriMapping(
+ TEST_PACKAGE_NAME_2, TEST_URI_2, TEST_ALIAS_2).build();
+
+ credentialManagementApp.setAuthenticationPolicy(updatedAuthenticationPolicy);
+
+ assertThat(credentialManagementApp.getAuthenticationPolicy(),
+ is(updatedAuthenticationPolicy));
+ }
+
+ @Test
+ public void constructor_nullPackageName_throwException() {
+ try {
+ new CredentialManagementApp(/* packageName= */ null, AUTHENTICATION_POLICY);
+ fail("Shall not take null inputs");
+ } catch (NullPointerException expected) {
+ // Expected behavior, nothing to do.
+ }
+ }
+
+ @Test
+ public void constructor_nullAuthenticationPolicy_throwException() {
+ try {
+ new CredentialManagementApp(PACKAGE_NAME, /* authenticationPolicy= */ null);
+ fail("Shall not take null inputs");
+ } catch (NullPointerException expected) {
+ // Expected behavior, nothing to do.
+ }
+ }
+
+ @Test
+ public void writeToXmlAndReadFromXml() throws IOException, XmlPullParserException {
+ File xmlFile = writeToXml(CREDENTIAL_MANAGEMENT_APP);
+
+ CredentialManagementApp loadedCredentialManagementApp = readFromXml(xmlFile);
+
+ assertCredentialManagementAppsEqual(loadedCredentialManagementApp,
+ CREDENTIAL_MANAGEMENT_APP);
+ }
+
+ private File writeToXml(CredentialManagementApp credentialManagementApp) throws IOException {
+ File file = File.createTempFile("temp", "credmng");
+ final FileOutputStream out = new FileOutputStream(file);
+ XmlSerializer xml = Xml.newSerializer();
+ xml.setOutput(out, StandardCharsets.UTF_8.name());
+ xml.startDocument(null, true);
+ xml.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ xml.startTag(null, TAG_CREDENTIAL_MANAGEMENT_APP);
+ credentialManagementApp.writeToXml(xml);
+ xml.endTag(null, TAG_CREDENTIAL_MANAGEMENT_APP);
+ xml.endDocument();
+ out.close();
+ return file;
+ }
+
+ private CredentialManagementApp readFromXml(File file)
+ throws IOException, XmlPullParserException {
+ CredentialManagementApp credentialManagementApp = null;
+ final XmlPullParser parser = Xml.newPullParser();
+ final FileInputStream in = new FileInputStream(file);
+ parser.setInput(in, StandardCharsets.UTF_8.name());
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ }
+ String tag = parser.getName();
+ if (TAG_CREDENTIAL_MANAGEMENT_APP.equals(tag)) {
+ credentialManagementApp = CredentialManagementApp.readFromXml(parser);
+ }
+ return credentialManagementApp;
+ }
+
+ private void assertCredentialManagementAppsEqual(CredentialManagementApp actual,
+ CredentialManagementApp expected) {
+ assertThat(actual.getPackageName(), is(expected.getPackageName()));
+ assertAuthenticationPoliciesEqual(actual.getAuthenticationPolicy(),
+ expected.getAuthenticationPolicy());
+ }
+
+ private void assertAuthenticationPoliciesEqual(AppUriAuthenticationPolicy actual,
+ AppUriAuthenticationPolicy expected) {
+ Iterator<Map.Entry<String, Map<Uri, String>>> actualIter =
+ actual.getAppAndUriMappings().entrySet().iterator();
+ Iterator<Map.Entry<String, Map<Uri, String>>> expectedIter =
+ expected.getAppAndUriMappings().entrySet().iterator();
+
+ assertThat(actual.getAppAndUriMappings().size(),
+ is(expected.getAppAndUriMappings().size()));
+ while (actualIter.hasNext()) {
+ Map.Entry<String, Map<Uri, String>> actualAppToUri = actualIter.next();
+ Map.Entry<String, Map<Uri, String>> expectedAppToUri = expectedIter.next();
+ assertThat(actualAppToUri.getKey(), is(expectedAppToUri.getKey()));
+ assertUrisToAliasesEqual(actualAppToUri.getValue(), expectedAppToUri.getValue());
+ }
+ }
+
+ private void assertUrisToAliasesEqual(Map<Uri, String> actual, Map<Uri, String> expected) {
+ Iterator<Map.Entry<Uri, String>> actualIter = actual.entrySet().iterator();
+ Iterator<Map.Entry<Uri, String>> expectedIter = expected.entrySet().iterator();
+
+ assertThat(actual.size(), is(expected.size()));
+ while (actualIter.hasNext()) {
+ Map.Entry<Uri, String> actualUriToAlias = actualIter.next();
+ Map.Entry<Uri, String> expectedUriToAlias = expectedIter.next();
+ assertThat(actualUriToAlias.getKey(), is(expectedUriToAlias.getKey()));
+ assertThat(actualUriToAlias.getValue(), is(expectedUriToAlias.getValue()));
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 7cde19c30dd4..40ef04a5e369 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -376,6 +376,56 @@ public class TextViewActivityTest {
}
@Test
+ public void testToolbarMenuItemClickAfterSelectionChange() throws Throwable {
+ final MenuItem[] latestItem = new MenuItem[1];
+ final MenuItem[] clickedItem = new MenuItem[1];
+ final String text = "abcd efg hijk";
+ mActivityRule.runOnUiThread(() -> {
+ final TextView textView = mActivity.findViewById(R.id.textview);
+ textView.setText(text);
+ textView.setCustomSelectionActionModeCallback(
+ new ActionMode.Callback() {
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ menu.clear();
+ latestItem[0] = menu.add("Item");
+ return true;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ clickedItem[0] = item;
+ return true;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {}
+ });
+ });
+ mInstrumentation.waitForIdleSync();
+
+ onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f")));
+ sleepForFloatingToolbarPopup();
+
+ // Change the selection so that the menu items are refreshed.
+ final TextView textView = mActivity.findViewById(R.id.textview);
+ onHandleView(com.android.internal.R.id.selection_start_handle)
+ .perform(dragHandle(textView, Handle.SELECTION_START, 0));
+ sleepForFloatingToolbarPopup();
+ assertFloatingToolbarIsDisplayed();
+
+ clickFloatingToolbarItem("Item");
+ mInstrumentation.waitForIdleSync();
+
+ assertEquals(latestItem[0], clickedItem[0]);
+ }
+
+ @Test
public void testSelectionRemovedWhenNonselectableTextLosesFocus() throws Throwable {
final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
final int position = (textLink.getStart() + textLink.getEnd()) / 2;
diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
index d45d4b04af33..477978630ec2 100644
--- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
@@ -28,10 +28,11 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static com.android.internal.widget.FloatingToolbar.MenuItemRepr;
+
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -158,8 +159,8 @@ public class FloatingToolbarEspressoUtils {
public void describeTo(Description description) {}
private void collectMenuItemIds(View view) {
- if (view.getTag() instanceof MenuItem) {
- menuItemIds.add(((MenuItem) view.getTag()).getItemId());
+ if (view.getTag() instanceof MenuItemRepr) {
+ menuItemIds.add(((MenuItemRepr) view.getTag()).itemId);
} else if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
@@ -178,8 +179,8 @@ public class FloatingToolbarEspressoUtils {
*/
public static void assertFloatingToolbarDoesNotContainItem(String itemLabel) {
final Predicate<View> hasMenuItemLabel = view ->
- view.getTag() instanceof MenuItem
- && itemLabel.equals(((MenuItem) view.getTag()).getTitle().toString());
+ view.getTag() instanceof MenuItemRepr
+ && itemLabel.equals(((MenuItemRepr) view.getTag()).title);
assertFloatingToolbarMenuItem(hasMenuItemLabel, false);
}
@@ -191,8 +192,8 @@ public class FloatingToolbarEspressoUtils {
*/
public static void assertFloatingToolbarDoesNotContainItem(final int menuItemId) {
final Predicate<View> hasMenuItemId = view ->
- view.getTag() instanceof MenuItem
- && ((MenuItem) view.getTag()).getItemId() == menuItemId;
+ view.getTag() instanceof MenuItemRepr
+ && ((MenuItemRepr) view.getTag()).itemId == menuItemId;
assertFloatingToolbarMenuItem(hasMenuItemId, false);
}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 10310237f89b..a52eca7e0d73 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1561,6 +1561,12 @@
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
"at": "com\/android\/server\/wm\/Transition.java"
},
+ "-292790591": {
+ "message": "Attempted to set IME policy to a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"-279436615": {
"message": "Moving to PAUSING: %s",
"level": "VERBOSE",
@@ -1819,12 +1825,6 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
},
- "91350919": {
- "message": "Attempted to set IME flag to a display that does not exist: %d",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"94402792": {
"message": "Moving to RESUMED: %s (in existing)",
"level": "VERBOSE",
@@ -1837,12 +1837,6 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "95281111": {
- "message": "Attempted to get IME flag of a display that does not exist: %d",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"95902367": {
"message": "Relayout of %s: focusMayChange=%b",
"level": "VERBOSE",
@@ -2749,6 +2743,12 @@
"group": "WM_SHOW_SURFACE_ALLOC",
"at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
},
+ "1100065297": {
+ "message": "Attempted to get IME policy of a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"1112047265": {
"message": "finishDrawingWindow: %s mDrawState=%s",
"level": "DEBUG",
diff --git a/core/proto/android/stats/storage/storage_enums.proto b/keystore/java/android/security/AppUriAuthenticationPolicy.aidl
index 6892e287472f..5c52c86f0426 100644
--- a/core/proto/android/stats/storage/storage_enums.proto
+++ b/keystore/java/android/security/AppUriAuthenticationPolicy.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,6 @@
* limitations under the License.
*/
-syntax = "proto2";
+package android.security;
-package android.stats.storage;
-
-enum ExternalStorageType {
- UNKNOWN = 0;
- SD_CARD = 1;
- USB = 2;
- OTHER = 3;
-}
+parcelable AppUriAuthenticationPolicy;
diff --git a/keystore/java/android/security/AppUriAuthenticationPolicy.java b/keystore/java/android/security/AppUriAuthenticationPolicy.java
new file mode 100644
index 000000000000..30f5a94ca0c8
--- /dev/null
+++ b/keystore/java/android/security/AppUriAuthenticationPolicy.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * The app-URI authentication policy is set by the credential management app. This policy determines
+ * which alias for a private key and certificate pair should be used for authentication.
+ * <p>
+ * The authentication policy should be added as a parameter when calling
+ * {@link KeyChain#createManageCredentialsIntent}.
+ * <p>
+ * Example:
+ * <pre>{@code
+ * AppUriAuthenticationPolicy authenticationPolicy = new AppUriAuthenticationPolicy.Builder()
+ * .addAppAndUriMapping("com.test.pkg", testUri, "testAlias")
+ * .addAppAndUriMapping("com.test2.pkg", testUri1, "testAlias2")
+ * .addAppAndUriMapping("com.test2.pkg", testUri2, "testAlias2")
+ * .build();
+ * Intent requestIntent = KeyChain.createManageCredentialsIntent(authenticationPolicy);
+ * }</pre>
+ * <p>
+ */
+public final class AppUriAuthenticationPolicy implements Parcelable {
+
+ private static final String KEY_AUTHENTICATION_POLICY_APP_TO_URIS =
+ "authentication_policy_app_to_uris";
+ private static final String KEY_AUTHENTICATION_POLICY_APP = "policy_app";
+
+ /**
+ * The mappings from an app and list of URIs to a list of aliases, which will be used for
+ * authentication.
+ * <p>
+ * appPackageName -> uri -> alias
+ */
+ @NonNull
+ private final Map<String, UrisToAliases> mAppToUris;
+
+ private AppUriAuthenticationPolicy(@NonNull Map<String, UrisToAliases> appToUris) {
+ Objects.requireNonNull(appToUris);
+ this.mAppToUris = appToUris;
+ }
+
+ /**
+ * Builder class for {@link AppUriAuthenticationPolicy} objects.
+ */
+ public static final class Builder {
+ private Map<String, UrisToAliases> mPackageNameToUris;
+
+ /**
+ * Initialize a new Builder to construct an {@link AppUriAuthenticationPolicy}.
+ */
+ public Builder() {
+ mPackageNameToUris = new HashMap<>();
+ }
+
+ /**
+ * Adds mappings from an app and URI to an alias, which will be used for authentication.
+ * <p>
+ * If this method is called with a package name and URI that was previously added, the
+ * previous alias will be overwritten.
+ *
+ * @param appPackageName The app's package name to authenticate the user to.
+ * @param uri The URI to authenticate the user to.
+ * @param alias The alias which will be used for authentication.
+ *
+ * @return the same Builder instance.
+ */
+ @NonNull
+ public Builder addAppAndUriMapping(@NonNull String appPackageName, @NonNull Uri uri,
+ @NonNull String alias) {
+ Objects.requireNonNull(appPackageName);
+ Objects.requireNonNull(uri);
+ Objects.requireNonNull(alias);
+ UrisToAliases urisToAliases =
+ mPackageNameToUris.getOrDefault(appPackageName, new UrisToAliases());
+ urisToAliases.addUriToAlias(uri, alias);
+ mPackageNameToUris.put(appPackageName, urisToAliases);
+ return this;
+ }
+
+ /**
+ * Adds mappings from an app and list of URIs to a list of aliases, which will be used for
+ * authentication.
+ * <p>
+ * appPackageName -> uri -> alias
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder addAppAndUriMapping(@NonNull String appPackageName,
+ @NonNull UrisToAliases urisToAliases) {
+ Objects.requireNonNull(appPackageName);
+ Objects.requireNonNull(urisToAliases);
+ mPackageNameToUris.put(appPackageName, urisToAliases);
+ return this;
+ }
+
+ /**
+ * Combines all of the attributes that have been set on the {@link Builder}
+ *
+ * @return a new {@link AppUriAuthenticationPolicy} object.
+ */
+ @NonNull
+ public AppUriAuthenticationPolicy build() {
+ return new AppUriAuthenticationPolicy(mPackageNameToUris);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeMap(mAppToUris);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<AppUriAuthenticationPolicy> CREATOR =
+ new Parcelable.Creator<AppUriAuthenticationPolicy>() {
+ @Override
+ public AppUriAuthenticationPolicy createFromParcel(Parcel in) {
+ Map<String, UrisToAliases> appToUris = new HashMap<>();
+ in.readMap(appToUris, UrisToAliases.class.getClassLoader());
+ return new AppUriAuthenticationPolicy(appToUris);
+ }
+
+ @Override
+ public AppUriAuthenticationPolicy[] newArray(int size) {
+ return new AppUriAuthenticationPolicy[size];
+ }
+ };
+
+ @Override
+ public String toString() {
+ return "AppUriAuthenticationPolicy{"
+ + "mPackageNameToUris=" + mAppToUris
+ + '}';
+ }
+
+ /**
+ * Return the authentication policy mapping, which determines which alias for a private key
+ * and certificate pair should be used for authentication.
+ * <p>
+ * appPackageName -> uri -> alias
+ */
+ @NonNull
+ public Map<String, Map<Uri, String>> getAppAndUriMappings() {
+ Map<String, Map<Uri, String>> appAndUris = new HashMap<>();
+ for (Map.Entry<String, UrisToAliases> entry : mAppToUris.entrySet()) {
+ appAndUris.put(entry.getKey(), entry.getValue().getUrisToAliases());
+ }
+ return appAndUris;
+ }
+
+ /**
+ * Restore a previously saved {@link AppUriAuthenticationPolicy} from XML.
+ *
+ * @hide
+ */
+ @Nullable
+ public static AppUriAuthenticationPolicy readFromXml(@NonNull XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ AppUriAuthenticationPolicy.Builder builder = new AppUriAuthenticationPolicy.Builder();
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ if (!parser.getName().equals(KEY_AUTHENTICATION_POLICY_APP_TO_URIS)) {
+ continue;
+ }
+ String app = parser.getAttributeValue(null, KEY_AUTHENTICATION_POLICY_APP);
+ UrisToAliases urisToAliases = UrisToAliases.readFromXml(parser);
+ builder.addAppAndUriMapping(app, urisToAliases);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Save the {@link AppUriAuthenticationPolicy} to XML.
+ *
+ * @hide
+ */
+ public void writeToXml(@NonNull XmlSerializer out) throws IOException {
+ for (Map.Entry<String, UrisToAliases> appsToUris : mAppToUris.entrySet()) {
+ out.startTag(null, KEY_AUTHENTICATION_POLICY_APP_TO_URIS);
+ out.attribute(null, KEY_AUTHENTICATION_POLICY_APP, appsToUris.getKey());
+ appsToUris.getValue().writeToXml(out);
+ out.endTag(null, KEY_AUTHENTICATION_POLICY_APP_TO_URIS);
+ }
+ }
+
+}
diff --git a/keystore/java/android/security/CredentialManagementApp.java b/keystore/java/android/security/CredentialManagementApp.java
new file mode 100644
index 000000000000..cbb23015dbe8
--- /dev/null
+++ b/keystore/java/android/security/CredentialManagementApp.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * The credential management app has the ability to manage the user's KeyChain credentials on
+ * unmanaged devices. {@link KeyChain#createManageCredentialsIntent} should be used by an app to
+ * request to become the credential management app. The user must approve this request before the
+ * app can manage the user's credentials.
+ * <p>
+ * Note: there can only be one credential management on the device. If another app requests to
+ * become the credential management app and the user approves, then the existing credential
+ * management app will no longer be able to manage credentials.
+ * <p>
+ * The requesting credential management app should include its authentication policy in the
+ * requesting intent. The authentication policy declares which certificates should be used for a
+ * given list of apps and URIs.
+ *
+ * @hide
+ * @see AppUriAuthenticationPolicy
+ */
+public class CredentialManagementApp {
+
+ private static final String TAG = "CredentialManagementApp";
+ private static final String KEY_PACKAGE_NAME = "package_name";
+
+ /**
+ * The credential management app's package name
+ */
+ @NonNull
+ private final String mPackageName;
+
+ /**
+ * The mappings from an app and list of URIs to a list of aliases, which will be used for
+ * authentication.
+ * <p>
+ * appPackageName -> uri -> alias
+ */
+ @NonNull
+ private AppUriAuthenticationPolicy mAuthenticationPolicy;
+
+ public CredentialManagementApp(@NonNull String packageName,
+ @NonNull AppUriAuthenticationPolicy authenticationPolicy) {
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(authenticationPolicy);
+ mPackageName = packageName;
+ mAuthenticationPolicy = authenticationPolicy;
+ }
+
+ /**
+ * Returns the package name of the credential management app.
+ */
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /**
+ * Returns the authentication policy of the credential management app.
+ */
+ @NonNull
+ public AppUriAuthenticationPolicy getAuthenticationPolicy() {
+ return mAuthenticationPolicy;
+ }
+
+ /**
+ * Sets the authentication policy of the credential management app.
+ */
+ public void setAuthenticationPolicy(@Nullable AppUriAuthenticationPolicy authenticationPolicy) {
+ Objects.requireNonNull(authenticationPolicy);
+ mAuthenticationPolicy = authenticationPolicy;
+ }
+
+ /**
+ * Restore a previously saved {@link CredentialManagementApp} from XML.
+ */
+ @Nullable
+ public static CredentialManagementApp readFromXml(@NonNull XmlPullParser parser) {
+ try {
+ String packageName = parser.getAttributeValue(null, KEY_PACKAGE_NAME);
+ AppUriAuthenticationPolicy policy = AppUriAuthenticationPolicy.readFromXml(parser);
+ return new CredentialManagementApp(packageName, policy);
+ } catch (XmlPullParserException | IOException e) {
+ Log.w(TAG, "Reading from xml failed", e);
+ }
+ return null;
+ }
+
+ /**
+ * Save the {@link CredentialManagementApp} to XML.
+ */
+ public void writeToXml(@NonNull XmlSerializer out) throws IOException {
+ out.attribute(null, KEY_PACKAGE_NAME, mPackageName);
+ if (mAuthenticationPolicy != null) {
+ mAuthenticationPolicy.writeToXml(out);
+ }
+ }
+}
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 7abcfdc98bc6..f41b6081e38c 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -49,6 +49,8 @@ public class Credentials {
public static final String INSTALL_AS_USER_ACTION = "android.credentials.INSTALL_AS_USER";
+ public static final String ACTION_MANAGE_CREDENTIALS = "android.security.MANAGE_CREDENTIALS";
+
/**
* Key prefix for CA certificates.
*
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index a77aec2788af..c6e72b0e9f6e 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -15,6 +15,8 @@
*/
package android.security;
+import static android.security.Credentials.ACTION_MANAGE_CREDENTIALS;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
@@ -122,6 +124,11 @@ public final class KeyChain {
private static final String CERT_INSTALLER_PACKAGE = "com.android.certinstaller";
/**
+ * Package name for Settings.
+ */
+ private static final String SETTINGS_PACKAGE = "com.android.settings";
+
+ /**
* Extra for use with {@link #ACTION_CHOOSER}
* @hide Also used by KeyChainActivity implementation
*/
@@ -202,6 +209,20 @@ public final class KeyChain {
public static final String EXTRA_PKCS12 = "PKCS12";
/**
+ * Extra used by {@link #createManageCredentialsIntent(AppUriAuthenticationPolicy)} to specify
+ * the authentication policy of the credential management app.
+ *
+ * <p>The authentication policy declares which alias for a private key and certificate pair
+ * should be used for authentication, given a list of apps and URIs.
+ *
+ * <p>The extra value should be a {@link AppUriAuthenticationPolicy}.
+ *
+ * @hide
+ */
+ public static final String EXTRA_AUTHENTICATION_POLICY =
+ "android.security.extra.AUTHENTICATION_POLICY";
+
+ /**
* Broadcast Action: Indicates the trusted storage has changed. Sent when
* one of this happens:
*
@@ -386,6 +407,23 @@ public final class KeyChain {
}
/**
+ * Returns an {@code Intent} that should be used by an app to request to manage the user's
+ * credentials. This is limited to unmanaged devices. The authentication policy must be
+ * provided to be able to make this request successfully.
+ *
+ * @param policy The authentication policy determines which alias for a private key and
+ * certificate pair should be used for authentication.
+ */
+ @NonNull
+ public static Intent createManageCredentialsIntent(@NonNull AppUriAuthenticationPolicy policy) {
+ Intent intent = new Intent(ACTION_MANAGE_CREDENTIALS);
+ intent.setComponent(ComponentName.createRelative(SETTINGS_PACKAGE,
+ ".security.RequestManageCredentials"));
+ intent.putExtra(EXTRA_AUTHENTICATION_POLICY, policy);
+ return intent;
+ }
+
+ /**
* Launches an {@code Activity} for the user to select the alias
* for a private key and certificate pair for authentication. The
* selected alias or null will be returned via the
diff --git a/keystore/java/android/security/UrisToAliases.java b/keystore/java/android/security/UrisToAliases.java
new file mode 100644
index 000000000000..65d433abe166
--- /dev/null
+++ b/keystore/java/android/security/UrisToAliases.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The mapping from URI to alias, which determines the alias to use when the user visits a URI.
+ * This mapping is part of the {@link AppUriAuthenticationPolicy}, which specifies which app this
+ * mapping should be used for.
+ *
+ * @hide
+ * @see AppUriAuthenticationPolicy
+ */
+public final class UrisToAliases implements Parcelable {
+
+ private static final String KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS =
+ "authentication_policy_uri_to_alias";
+ private static final String KEY_AUTHENTICATION_POLICY_URI = "policy_uri";
+ private static final String KEY_AUTHENTICATION_POLICY_ALIAS = "policy_alias";
+
+ /**
+ * The mappings from URIs to aliases, which will be used for authentication.
+ */
+ @NonNull
+ private final Map<Uri, String> mUrisToAliases;
+
+ public UrisToAliases() {
+ this.mUrisToAliases = new HashMap<>();
+ }
+
+ private UrisToAliases(@NonNull Map<Uri, String> urisToAliases) {
+ this.mUrisToAliases = urisToAliases;
+ }
+
+ @NonNull
+ public static final Creator<UrisToAliases> CREATOR = new Creator<UrisToAliases>() {
+ @Override
+ public UrisToAliases createFromParcel(Parcel in) {
+ Map<Uri, String> urisToAliases = new HashMap<>();
+ in.readMap(urisToAliases, String.class.getClassLoader());
+ return new UrisToAliases(urisToAliases);
+ }
+
+ @Override
+ public UrisToAliases[] newArray(int size) {
+ return new UrisToAliases[size];
+ }
+ };
+
+ /**
+ * Returns the mapping from URIs to aliases.
+ */
+ @NonNull
+ public Map<Uri, String> getUrisToAliases() {
+ return Collections.unmodifiableMap(mUrisToAliases);
+ }
+
+ /**
+ * Adds mapping from an URI to an alias.
+ */
+ public void addUriToAlias(@NonNull Uri uri, @NonNull String alias) {
+ mUrisToAliases.put(uri, alias);
+ }
+
+ /**
+ * Restore a previously saved {@link UrisToAliases} from XML.
+ */
+ @Nullable
+ public static UrisToAliases readFromXml(@NonNull XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ Map<Uri, String> urisToAliases = new HashMap<>();
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ if (!parser.getName().equals(KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS)) {
+ continue;
+ }
+ Uri uri = Uri.parse(parser.getAttributeValue(null, KEY_AUTHENTICATION_POLICY_URI));
+ String alias = parser.getAttributeValue(null, KEY_AUTHENTICATION_POLICY_ALIAS);
+ urisToAliases.put(uri, alias);
+ }
+ return new UrisToAliases(urisToAliases);
+ }
+
+ /**
+ * Save the {@link UrisToAliases} to XML.
+ */
+ public void writeToXml(@NonNull XmlSerializer out) throws IOException {
+ for (Map.Entry<Uri, String> urisToAliases : mUrisToAliases.entrySet()) {
+ out.startTag(null, KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS);
+ out.attribute(null, KEY_AUTHENTICATION_POLICY_URI, urisToAliases.getKey().toString());
+ out.attribute(null, KEY_AUTHENTICATION_POLICY_ALIAS, urisToAliases.getValue());
+ out.endTag(null, KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeMap(mUrisToAliases);
+ }
+}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 5867ef6eaea5..b1b6306e0cf6 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -83,8 +83,7 @@ public class AndroidKeyStoreProvider extends Provider {
boolean supports3DES = "true".equals(android.os.SystemProperties.get(DESEDE_SYSTEM_PROPERTY));
// java.security.KeyStore
- put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStoreSpi");
- put("Alg.Alias.KeyStore.AndroidKeyStoreLegacy", "AndroidKeyStore");
+ put("KeyStore." + providerName, PACKAGE_NAME + ".AndroidKeyStoreSpi");
// java.security.KeyPairGenerator
put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java
index 388eb28223dc..120039de1240 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java
@@ -116,7 +116,7 @@ public class Transitions extends ITransitionPlayer.Stub {
}
@Override
- public void onTransitionReady(@NonNull IBinder transitionToken, TransitionInfo info,
+ public void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady %s: %s",
transitionToken, info);
@@ -131,22 +131,53 @@ public class Transitions extends ITransitionPlayer.Stub {
+ transitionToken);
}
mActiveTransitions.put(transitionToken, new ArrayList<>());
- for (int i = 0; i < info.getChanges().size(); ++i) {
- final SurfaceControl leash = info.getChanges().get(i).getLeash();
+ boolean isOpening = isOpeningType(info.getType());
+ if (info.getRootLeash().isValid()) {
+ t.show(info.getRootLeash());
+ }
+ // changes should be ordered top-to-bottom in z
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final SurfaceControl leash = change.getLeash();
final int mode = info.getChanges().get(i).getMode();
+
+ // Don't animate anything with an animating parent
+ if (change.getParent() != null) {
+ if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) {
+ t.show(leash);
+ t.setMatrix(leash, 1, 0, 0, 1);
+ }
+ continue;
+ }
+
+ t.reparent(leash, info.getRootLeash());
+ t.setPosition(leash, change.getEndAbsBounds().left - info.getRootOffset().x,
+ change.getEndAbsBounds().top - info.getRootOffset().y);
+ // Put all the OPEN/SHOW on top
if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) {
t.show(leash);
t.setMatrix(leash, 1, 0, 0, 1);
- if (isOpeningType(info.getType())) {
+ if (isOpening) {
+ // put on top and fade in
+ t.setLayer(leash, info.getChanges().size() - i);
t.setAlpha(leash, 0.f);
startExampleAnimation(transitionToken, leash, true /* show */);
} else {
+ // put on bottom and leave it visible without fade
+ t.setLayer(leash, -i);
t.setAlpha(leash, 1.f);
}
} else if (mode == TRANSIT_CLOSE || mode == TRANSIT_HIDE) {
- if (!isOpeningType(info.getType())) {
+ if (isOpening) {
+ // put on bottom and leave visible without fade
+ t.setLayer(leash, -i);
+ } else {
+ // put on top and fade out
+ t.setLayer(leash, info.getChanges().size() - i);
startExampleAnimation(transitionToken, leash, false /* show */);
}
+ } else {
+ t.setLayer(leash, info.getChanges().size() - i);
}
}
t.apply();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
index 090d2270817b..4e62ea6e7233 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
@@ -272,8 +272,9 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
@VisibleForTesting
void applyBoundsAndOffsets(WindowContainerToken token, SurfaceControl leash,
WindowContainerTransaction wct, SurfaceControl.Transaction t) {
- wct.setBounds(token, mCurrentDisplayBounds.isEmpty() ? null : mCurrentDisplayBounds);
+ wct.setBounds(token, mCurrentDisplayBounds);
t.setPosition(leash, mOffsetX, mOffsetY);
+ t.setWindowCrop(leash, mCurrentDisplayBounds.width(), mCurrentDisplayBounds.height());
}
@VisibleForTesting
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index 1bbe6884a48c..4a498d2ec581 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -33,6 +33,7 @@ android_test {
"wm-flicker-common-assertions",
"wm-flicker-common-app-helpers",
"platform-test-annotations",
+ "wmshell-flicker-test-components",
],
}
@@ -54,5 +55,6 @@ android_test {
"wm-flicker-common-assertions",
"wm-flicker-common-app-helpers",
"platform-test-annotations",
+ "wmshell-flicker-test-components",
],
}
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
index 9e8330973b40..101b5bf27c77 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
@@ -36,6 +36,8 @@
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
<!-- Control test app's media session -->
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <!-- ATM.removeRootTasksWithActivityTypes() -->
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
<application>
<uses-library android:name="android.test.runner"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index bbf5afcff67a..96234fcc8570 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -16,35 +16,24 @@
package com.android.wm.shell.flicker
-import android.content.ComponentName
-
const val IME_WINDOW_NAME = "InputMethod"
-const val PIP_WINDOW_NAME = "PipMenuActivity"
-const val SPLITSCREEN_PRIMARY_WINDOW_NAME = "SplitScreenActivity"
-const val SPLITSCREEN_SECONDARY_WINDOW_NAME = "SplitScreenSecondaryActivity"
+const val PIP_MENU_WINDOW_NAME = "PipMenuActivity"
const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
const val TEST_APP_PACKAGE_NAME = "com.android.wm.shell.flicker.testapp"
// Test App > Pip Activity
-val TEST_APP_PIP_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
- TEST_APP_PACKAGE_NAME, ".PipActivity")
const val TEST_APP_PIP_ACTIVITY_LABEL = "PipApp"
-const val TEST_APP_PIP_ACTIVITY_WINDOW_NAME = "PipActivity"
const val TEST_APP_PIP_MENU_ACTION_NO_OP = "No-Op"
const val TEST_APP_PIP_MENU_ACTION_ON = "On"
const val TEST_APP_PIP_MENU_ACTION_OFF = "Off"
const val TEST_APP_PIP_MENU_ACTION_CLEAR = "Clear"
// Test App > Ime Activity
-val TEST_APP_IME_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
- TEST_APP_PACKAGE_NAME, ".ImeActivity")
const val TEST_APP_IME_ACTIVITY_LABEL = "ImeApp"
+// Test App > Test Activity
+const val TEST_APP_FIXED_ACTIVITY_LABEL = "FixedApp"
// Test App > SplitScreen Activity
-val TEST_APP_SPLITSCREEN_PRIMARY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
- TEST_APP_PACKAGE_NAME, ".$SPLITSCREEN_PRIMARY_WINDOW_NAME")
-val TEST_APP_SPLITSCREEN_SECONDARY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
- TEST_APP_PACKAGE_NAME, ".$SPLITSCREEN_SECONDARY_WINDOW_NAME")
const val TEST_APP_SPLITSCREEN_PRIMARY_LABEL = "SplitScreenPrimaryApp"
const val TEST_APP_SPLITSCREEN_SECONDARY_LABEL = "SplitScreenSecondaryApp"
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt
index 1a4de0a80bec..f32cd8842074 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt
@@ -17,12 +17,11 @@
package com.android.wm.shell.flicker.apppairs
import com.android.wm.shell.flicker.NonRotationTestBase
-import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_LABEL
-import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_LABEL
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import com.android.wm.shell.flicker.testapp.Components
abstract class AppPairsTestBase(
rotationName: String,
@@ -30,11 +29,11 @@ abstract class AppPairsTestBase(
) : NonRotationTestBase(rotationName, rotation) {
protected val appPairsHelper = AppPairsHelper(instrumentation,
TEST_APP_SPLITSCREEN_PRIMARY_LABEL,
- TEST_APP_SPLITSCREEN_PRIMARY_COMPONENT_NAME)
+ Components.SplitScreenActivity())
protected val primaryApp = SplitScreenHelper(instrumentation,
TEST_APP_SPLITSCREEN_PRIMARY_LABEL,
- TEST_APP_SPLITSCREEN_PRIMARY_COMPONENT_NAME)
+ Components.SplitScreenActivity())
protected val secondaryApp = SplitScreenHelper(instrumentation,
TEST_APP_SPLITSCREEN_SECONDARY_LABEL,
- TEST_APP_SPLITSCREEN_SECONDARY_COMPONENT_NAME)
+ Components.SplitScreenSecondaryActivity())
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
index 3b6fcdbee4be..e2cda7ad123d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
@@ -17,19 +17,19 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import android.content.ComponentName
import android.graphics.Region
import android.system.helpers.ActivityHelper
import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.wm.shell.flicker.testapp.Components
class AppPairsHelper(
instrumentation: Instrumentation,
activityLabel: String,
- componentName: ComponentName
+ componentsInfo: Components.ComponentsInfo
) : BaseAppHelper(
instrumentation,
activityLabel,
- componentName
+ componentsInfo
) {
val activityHelper = ActivityHelper.getInstance()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
index 22496a506e0d..6fd1df3b3f30 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager.FEATURE_LEANBACK
@@ -28,15 +27,15 @@ import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.helpers.StandardAppHelper
-import com.android.wm.shell.flicker.TEST_APP_PACKAGE_NAME
+import com.android.wm.shell.flicker.testapp.Components
abstract class BaseAppHelper(
instrumentation: Instrumentation,
launcherName: String,
- private val launcherActivityComponent: ComponentName
+ private val componentsInfo: Components.ComponentsInfo
) : StandardAppHelper(
instrumentation,
- TEST_APP_PACKAGE_NAME,
+ Components.PACKAGE_NAME,
launcherName,
LauncherStrategyFactory.getInstance(instrumentation).launcherStrategy
) {
@@ -53,7 +52,7 @@ abstract class BaseAppHelper(
}
val defaultWindowName: String
- get() = launcherActivityComponent.className
+ get() = componentsInfo.activityName
val label: String
get() = context.packageManager.run {
@@ -63,8 +62,12 @@ abstract class BaseAppHelper(
val ui: UiObject2?
get() = uiDevice.findObject(appSelector)
- fun launchViaIntent() {
- context.startActivity(openAppIntent)
+ fun launchViaIntent(stringExtras: Map<String, String> = mapOf()) {
+ val intent = openAppIntent
+ stringExtras.forEach() {
+ intent.putExtra(it.key, it.value)
+ }
+ context.startActivity(intent)
uiDevice.wait(Until.hasObject(appSelector), APP_LAUNCH_WAIT_TIME_MS)
}
@@ -75,7 +78,7 @@ abstract class BaseAppHelper(
override fun getOpenAppIntent(): Intent {
val intent = Intent()
- intent.component = launcherActivityComponent
+ intent.component = componentsInfo.componentName
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
return intent
}
diff --git a/core/proto/android/stats/accessibility/accessibility_enums.proto b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FixedAppHelper.kt
index 5118ad5a322c..c7f19a5d2620 100644
--- a/core/proto/android/stats/accessibility/accessibility_enums.proto
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FixedAppHelper.kt
@@ -14,22 +14,16 @@
* limitations under the License.
*/
-syntax = "proto2";
-package android.stats.accessibility;
-option java_multiple_files = true;
+package com.android.wm.shell.flicker.helpers
-// The entry point of the accessibility shortcut.
-enum ShortcutType {
- UNKNOWN_TYPE = 0;
- A11Y_BUTTON = 1;
- VOLUME_KEY = 2;
- TRIPLE_TAP = 3;
- A11Y_BUTTON_LONG_PRESS = 4;
-}
+import android.app.Instrumentation
+import com.android.wm.shell.flicker.TEST_APP_FIXED_ACTIVITY_LABEL
+import com.android.wm.shell.flicker.testapp.Components
-// The service status code.
-enum ServiceStatus {
- UNKNOWN = 0;
- ENABLED = 1;
- DISABLED = 2;
-} \ No newline at end of file
+class FixedAppHelper(
+ instrumentation: Instrumentation
+) : BaseAppHelper(
+ instrumentation,
+ TEST_APP_FIXED_ACTIVITY_LABEL,
+ Components.FixedActivity()
+) \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
index a6650d7f13d1..d580104ade19 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
@@ -21,8 +21,8 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.helpers.FIND_TIMEOUT
import com.android.server.wm.flicker.helpers.waitForIME
-import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_LABEL
+import com.android.wm.shell.flicker.testapp.Components
import org.junit.Assert
open class ImeAppHelper(
@@ -30,7 +30,7 @@ open class ImeAppHelper(
) : BaseAppHelper(
instrumentation,
TEST_APP_IME_ACTIVITY_LABEL,
- TEST_APP_IME_ACTIVITY_COMPONENT_NAME
+ Components.ImeActivity()
) {
fun openIME() {
val editText = uiDevice.wait(
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index e85ba9ef6da2..ed5f8a42258b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -26,8 +26,8 @@ import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.helpers.closePipWindow
import com.android.server.wm.flicker.helpers.hasPipWindow
import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
-import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_LABEL
+import com.android.wm.shell.flicker.testapp.Components
import org.junit.Assert.assertNotNull
import org.junit.Assert.fail
@@ -36,7 +36,7 @@ class PipAppHelper(
) : BaseAppHelper(
instrumentation,
TEST_APP_PIP_ACTIVITY_LABEL,
- TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
+ Components.PipActivity()
) {
private val mediaSessionManager: MediaSessionManager
get() = context.getSystemService(MediaSessionManager::class.java)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
index 10daa675ce36..e67fc97dad2e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
@@ -17,19 +17,19 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import android.content.ComponentName
import android.graphics.Region
import android.os.SystemClock
import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.wm.shell.flicker.testapp.Components
class SplitScreenHelper(
instrumentation: Instrumentation,
activityLabel: String,
- componentName: ComponentName
+ componentsInfo: Components.ComponentsInfo
) : BaseAppHelper(
instrumentation,
activityLabel,
- componentName
+ componentsInfo
) {
/**
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AppTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AppTestBase.kt
new file mode 100644
index 000000000000..2015f4941cea
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AppTestBase.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.app.ActivityTaskManager
+import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT
+import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
+import android.os.SystemClock
+import com.android.wm.shell.flicker.NonRotationTestBase
+
+abstract class AppTestBase(
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+ companion object {
+ fun removeAllTasksButHome() {
+ val ALL_ACTIVITY_TYPE_BUT_HOME = intArrayOf(
+ ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS,
+ ACTIVITY_TYPE_UNDEFINED)
+ val atm = ActivityTaskManager.getService()
+ atm.removeRootTasksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME)
+ }
+
+ fun waitForAnimationComplete() {
+ // TODO: UiDevice doesn't have reliable way to wait for the completion of animation.
+ // Consider to introduce WindowManagerStateHelper to access Activity state.
+ SystemClock.sleep(1000)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
new file mode 100644
index 000000000000..0663eb344f46
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.dsl.runFlicker
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.helpers.FixedAppHelper
+import com.android.wm.shell.flicker.helpers.PipAppHelper
+import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch and exit.
+ * To run this test: `atest WMShellFlickerTests:EnterExitPipTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class EnterExitPipTest(
+ rotationName: String,
+ rotation: Int
+) : AppTestBase(rotationName, rotation) {
+ private val pipApp = PipAppHelper(instrumentation)
+ private val testApp = FixedAppHelper(instrumentation)
+
+ @Test
+ fun testDisplayMetricsPinUnpin() {
+ runFlicker(instrumentation) {
+ withTestName { "testDisplayMetricsPinUnpin" }
+ setup {
+ test {
+ removeAllTasksButHome()
+ device.wakeUpAndGoToHomeScreen()
+ pipApp.launchViaIntent(stringExtras = mapOf(EXTRA_ENTER_PIP to "true"))
+ testApp.launchViaIntent()
+ waitForAnimationComplete()
+ }
+ }
+ transitions {
+ // This will bring PipApp to fullscreen
+ pipApp.launchViaIntent()
+ waitForAnimationComplete()
+ }
+ teardown {
+ test {
+ removeAllTasksButHome()
+ }
+ }
+ assertions {
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ windowManagerTrace {
+ all("pipApp must remain inside visible bounds") {
+ coversAtMostRegion(pipApp.defaultWindowName, displayBounds)
+ }
+ all("Initially shows both app windows then pipApp hides testApp") {
+ showsAppWindow(testApp.defaultWindowName)
+ .and().showsAppWindowOnTop(pipApp.defaultWindowName)
+ .then()
+ .hidesAppWindow(testApp.defaultWindowName)
+ }
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ layersTrace {
+ all("Initially shows both app layers then pipApp hides testApp") {
+ showsLayer(testApp.defaultWindowName)
+ .and().showsLayer(pipApp.defaultWindowName)
+ .then()
+ .hidesLayer(testApp.defaultWindowName)
+ }
+ start("testApp covers the fullscreen, pipApp remains inside display") {
+ hasVisibleRegion(testApp.defaultWindowName, displayBounds)
+ coversAtMostRegion(displayBounds, pipApp.defaultWindowName)
+ }
+ end("pipApp covers the fullscreen") {
+ hasVisibleRegion(pipApp.defaultWindowName, displayBounds)
+ }
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ }
+ }
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index abb8fc52abbb..6c4e65818e49 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -16,28 +16,21 @@
package com.android.wm.shell.flicker.pip
-import android.content.ComponentName
-import android.graphics.Region
-import android.util.Log
import android.view.Surface
-import android.view.WindowManager
import androidx.test.filters.RequiresDevice
-import com.android.compatibility.common.util.SystemUtil
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.dsl.runWithFlicker
+import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.closePipWindow
import com.android.server.wm.flicker.helpers.hasPipWindow
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_COMPONENT_NAME
import com.android.wm.shell.flicker.IME_WINDOW_NAME
-import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_WINDOW_NAME
import com.android.wm.shell.flicker.helpers.ImeAppHelper
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
-import java.io.IOException
/**
* Test Pip launch.
@@ -50,9 +43,6 @@ class PipKeyboardTest(
rotationName: String,
rotation: Int
) : PipTestBase(rotationName, rotation) {
- private val windowManager: WindowManager =
- instrumentation.context.getSystemService(WindowManager::class.java)
-
private val keyboardApp = ImeAppHelper(instrumentation)
private val keyboardScenario: FlickerBuilder
@@ -71,7 +61,7 @@ class PipKeyboardTest(
// open an app with an input field and a keyboard
// UiAutomator doesn't support to launch the multiple Activities in a task.
// So use launchActivity() for the Keyboard Activity.
- launchActivity(TEST_APP_IME_ACTIVITY_COMPONENT_NAME)
+ keyboardApp.launchViaIntent()
}
}
teardown {
@@ -103,10 +93,8 @@ class PipKeyboardTest(
assertions {
windowManagerTrace {
all("PiP window must remain inside visible bounds") {
- coversAtMostRegion(
- partialWindowTitle = "PipActivity",
- region = Region(windowManager.maximumWindowMetrics.bounds)
- )
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ coversAtMostRegion(testApp.defaultWindowName, displayBounds)
}
}
}
@@ -132,74 +120,13 @@ class PipKeyboardTest(
assertions {
windowManagerTrace {
end {
- isAboveWindow(IME_WINDOW_NAME, TEST_APP_PIP_ACTIVITY_WINDOW_NAME)
+ isAboveWindow(IME_WINDOW_NAME, testApp.defaultWindowName)
}
}
}
}
}
- private fun launchActivity(
- activity: ComponentName? = null,
- action: String? = null,
- flags: Set<Int> = setOf(),
- boolExtras: Map<String, Boolean> = mapOf(),
- intExtras: Map<String, Int> = mapOf(),
- stringExtras: Map<String, String> = mapOf()
- ) {
- require(activity != null || !action.isNullOrBlank()) {
- "Cannot launch an activity with neither activity name nor action!"
- }
- val command = composeCommand(
- "start", activity, action, flags, boolExtras, intExtras, stringExtras)
- executeShellCommand(command)
- }
-
- private fun composeCommand(
- command: String,
- activity: ComponentName?,
- action: String?,
- flags: Set<Int>,
- boolExtras: Map<String, Boolean>,
- intExtras: Map<String, Int>,
- stringExtras: Map<String, String>
- ): String = buildString {
- append("am ")
- append(command)
- activity?.let {
- append(" -n ")
- append(it.flattenToShortString())
- }
- action?.let {
- append(" -a ")
- append(it)
- }
- flags.forEach {
- append(" -f ")
- append(it)
- }
- boolExtras.forEach {
- append(it.withFlag("ez"))
- }
- intExtras.forEach {
- append(it.withFlag("ei"))
- }
- stringExtras.forEach {
- append(it.withFlag("es"))
- }
- }
-
- private fun Map.Entry<String, *>.withFlag(flag: String): String = " --$flag $key $value"
-
- private fun executeShellCommand(cmd: String): String {
- try {
- return SystemUtil.runShellCommand(instrumentation, cmd)
- } catch (e: IOException) {
- Log.e("FlickerTests", "Error running shell command: $cmd")
- throw e
- }
- }
-
companion object {
private const val TEST_REPETITIONS = 10
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt
new file mode 100644
index 000000000000..322034ce7688
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.content.Intent
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.dsl.runFlicker
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.helpers.FixedAppHelper
+import com.android.wm.shell.flicker.helpers.PipAppHelper
+import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_SET_REQUESTED_ORIENTATION
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_PIP_ORIENTATION
+import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION
+import org.junit.Assert.assertEquals
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip with orientation changes.
+ * To run this test: `atest WMShellFlickerTests:PipOrientationTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class PipOrientationTest(
+ rotationName: String,
+ rotation: Int
+) : AppTestBase(rotationName, rotation) {
+ // Helper class to process test actions by broadcast.
+ private inner class BroadcastActionTrigger {
+ private fun createIntentWithAction(broadcastAction: String): Intent {
+ return Intent(broadcastAction).setFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+ }
+ fun doAction(broadcastAction: String) {
+ instrumentation.getContext().sendBroadcast(createIntentWithAction(broadcastAction))
+ }
+ fun requestOrientationForPip(orientation: Int) {
+ instrumentation.getContext()
+ .sendBroadcast(createIntentWithAction(ACTION_SET_REQUESTED_ORIENTATION)
+ .putExtra(EXTRA_PIP_ORIENTATION, orientation.toString()))
+ }
+ }
+ private val broadcastActionTrigger = BroadcastActionTrigger()
+
+ // Corresponds to ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ private val ORIENTATION_LANDSCAPE = 0
+ // Corresponds to ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ private val ORIENTATION_PORTRAIT = 1
+
+ private val testApp = FixedAppHelper(instrumentation)
+ private val pipApp = PipAppHelper(instrumentation)
+
+ @Test
+ fun testEnterPipToOtherOrientation() {
+ runFlicker(instrumentation) {
+ withTestName { "testEnterPipToOtherOrientation" }
+ setup {
+ test {
+ removeAllTasksButHome()
+ device.wakeUpAndGoToHomeScreen()
+ // Launch a portrait only app on the fullscreen stack
+ testApp.launchViaIntent(stringExtras = mapOf(
+ EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString()))
+ waitForAnimationComplete()
+ // Launch the PiP activity fixed as landscape
+ pipApp.launchViaIntent(stringExtras = mapOf(
+ EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString()))
+ waitForAnimationComplete()
+ }
+ }
+ transitions {
+ // Enter PiP, and assert that the PiP is within bounds now that the device is back
+ // in portrait
+ broadcastActionTrigger.doAction(ACTION_ENTER_PIP)
+ waitForAnimationComplete()
+ }
+ teardown {
+ test {
+ removeAllTasksButHome()
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ all("pipApp window is always on top") {
+ showsAppWindowOnTop(pipApp.defaultWindowName)
+ }
+ start("pipApp window hides testApp") {
+ hidesAppWindow(testApp.defaultWindowName)
+ }
+ end("testApp windows is shown") {
+ showsAppWindow(testApp.defaultWindowName)
+ }
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ layersTrace {
+ val startingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_90)
+ val endingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_0)
+ start("pipApp layer hides testApp") {
+ hasVisibleRegion(pipApp.defaultWindowName, startingBounds)
+ hidesLayer(testApp.defaultWindowName)
+ }
+ end("testApp layer covers fullscreen") {
+ hasVisibleRegion(testApp.defaultWindowName, endingBounds)
+ }
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ }
+ }
+ }
+ }
+
+ @Test
+ fun testSetRequestedOrientationWhilePinned() {
+ runFlicker(instrumentation) {
+ withTestName { "testSetRequestedOrientationWhilePinned" }
+ setup {
+ test {
+ removeAllTasksButHome()
+ device.wakeUpAndGoToHomeScreen()
+ // Launch the PiP activity fixed as landscape
+ pipApp.launchViaIntent(stringExtras = mapOf(
+ EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString(),
+ EXTRA_ENTER_PIP to "true"))
+ waitForAnimationComplete()
+ assertEquals(Surface.ROTATION_0, device.displayRotation)
+ }
+ }
+ transitions {
+ // Request that the orientation is set to landscape
+ broadcastActionTrigger.requestOrientationForPip(ORIENTATION_LANDSCAPE)
+
+ // Launch the activity back into fullscreen and ensure that it is now in landscape
+ pipApp.launchViaIntent()
+ waitForAnimationComplete()
+ assertEquals(Surface.ROTATION_90, device.displayRotation)
+ }
+ teardown {
+ test {
+ removeAllTasksButHome()
+ }
+ }
+ assertions {
+ val startingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_0)
+ val endingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_90)
+ windowManagerTrace {
+ start("PIP window must remain inside display") {
+ coversAtMostRegion(pipApp.defaultWindowName, startingBounds)
+ }
+ end("pipApp shows on top") {
+ showsAppWindowOnTop(pipApp.defaultWindowName)
+ }
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ layersTrace {
+ start("PIP layer must remain inside display") {
+ coversAtMostRegion(startingBounds, pipApp.defaultWindowName)
+ }
+ end("pipApp layer covers fullscreen") {
+ hasVisibleRegion(pipApp.defaultWindowName, endingBounds)
+ }
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ }
+ }
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
new file mode 100644
index 000000000000..96d98d56e069
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.Flicker
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.repetitions
+import com.android.server.wm.flicker.startRotation
+import com.android.wm.shell.flicker.helpers.FixedAppHelper
+import com.android.wm.shell.flicker.helpers.PipAppHelper
+import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.navBarLayerRotatesAndScales
+import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.noUncoveredRegions
+import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarLayerRotatesScales
+import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip Stack in bounds after rotations.
+ * To run this test: `atest WMShellFlickerTests:PipRotationTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class PipRotationTest(
+ testName: String,
+ flickerSpec: Flicker
+) : FlickerTestRunner(testName, flickerSpec) {
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val instrumentation = InstrumentationRegistry.getInstrumentation()
+ val testApp = FixedAppHelper(instrumentation)
+ val pipApp = PipAppHelper(instrumentation)
+ return FlickerTestRunnerFactory(instrumentation,
+ listOf(Surface.ROTATION_0, Surface.ROTATION_90))
+ .buildRotationTest { configuration ->
+ withTestName { buildTestTag("PipRotationTest", testApp, configuration) }
+ repeat { configuration.repetitions }
+ setup {
+ test {
+ AppTestBase.removeAllTasksButHome()
+ device.wakeUpAndGoToHomeScreen()
+ pipApp.launchViaIntent(stringExtras = mapOf(
+ EXTRA_ENTER_PIP to "true"))
+ testApp.launchViaIntent()
+ AppTestBase.waitForAnimationComplete()
+ }
+ eachRun {
+ setRotation(configuration.startRotation)
+ }
+ }
+ transitions {
+ setRotation(configuration.endRotation)
+ }
+ teardown {
+ eachRun {
+ setRotation(Surface.ROTATION_0)
+ }
+ test {
+ AppTestBase.removeAllTasksButHome()
+ }
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ layersTrace {
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ noUncoveredRegions(configuration.startRotation,
+ configuration.endRotation, allStates = false)
+ navBarLayerRotatesAndScales(configuration.startRotation,
+ configuration.endRotation)
+ statusBarLayerRotatesScales(configuration.startRotation,
+ configuration.endRotation)
+ }
+ layersTrace {
+ val startingBounds = WindowUtils.getDisplayBounds(
+ configuration.startRotation)
+ val endingBounds = WindowUtils.getDisplayBounds(
+ configuration.endRotation)
+ start("appLayerRotates_StartingBounds") {
+ hasVisibleRegion(testApp.defaultWindowName, startingBounds)
+ coversAtMostRegion(startingBounds, pipApp.defaultWindowName)
+ }
+ end("appLayerRotates_EndingBounds") {
+ hasVisibleRegion(testApp.defaultWindowName, endingBounds)
+ coversAtMostRegion(endingBounds, pipApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt
new file mode 100644
index 000000000000..d20552f0739d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.dsl.runFlicker
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.helpers.ImeAppHelper
+import com.android.wm.shell.flicker.helpers.FixedAppHelper
+import com.android.wm.shell.flicker.helpers.PipAppHelper
+import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
+import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip with split-screen.
+ * To run this test: `atest WMShellFlickerTests:PipSplitScreenTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 161435597)
+class PipSplitScreenTest(
+ rotationName: String,
+ rotation: Int
+) : AppTestBase(rotationName, rotation) {
+ private val pipApp = PipAppHelper(instrumentation)
+ private val imeApp = ImeAppHelper(instrumentation)
+ private val testApp = FixedAppHelper(instrumentation)
+
+ @Test
+ fun testShowsPipLaunchingToSplitScreen() {
+ runFlicker(instrumentation) {
+ withTestName { "testShowsPipLaunchingToSplitScreen" }
+ repeat { TEST_REPETITIONS }
+ setup {
+ test {
+ removeAllTasksButHome()
+ device.wakeUpAndGoToHomeScreen()
+ pipApp.launchViaIntent(stringExtras = mapOf(EXTRA_ENTER_PIP to "true"))
+ waitForAnimationComplete()
+ }
+ }
+ transitions {
+ testApp.launchViaIntent()
+ device.launchSplitScreen()
+ imeApp.launchViaIntent()
+ waitForAnimationComplete()
+ }
+ teardown {
+ eachRun {
+ imeApp.exit()
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
+ }
+ testApp.exit()
+ }
+ test {
+ removeAllTasksButHome()
+ }
+ }
+ assertions {
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ windowManagerTrace {
+ all("PIP window must remain inside visible bounds") {
+ coversAtMostRegion(pipApp.defaultWindowName, displayBounds)
+ }
+ end("Both app windows should be visible") {
+ showsAppWindow(testApp.defaultWindowName)
+ showsAppWindow(imeApp.defaultWindowName)
+ noWindowsOverlap(testApp.defaultWindowName, imeApp.defaultWindowName)
+ }
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ }
+ layersTrace {
+ all("PIP layer must remain inside visible bounds") {
+ coversAtMostRegion(displayBounds, pipApp.defaultWindowName)
+ }
+ end("Both app layers should be visible") {
+ coversAtMostRegion(displayBounds, testApp.defaultWindowName)
+ coversAtMostRegion(displayBounds, imeApp.defaultWindowName)
+ }
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ }
+ }
+ }
+ }
+
+ companion object {
+ const val TEST_REPETITIONS = 2
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
index c1c34ecfbaec..03a92119fc86 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
@@ -16,12 +16,11 @@
package com.android.wm.shell.flicker.pip
-import com.android.wm.shell.flicker.NonRotationTestBase
import com.android.wm.shell.flicker.helpers.PipAppHelper
abstract class PipTestBase(
rotationName: String,
rotation: Int
-) : NonRotationTestBase(rotationName, rotation) {
+) : AppTestBase(rotationName, rotation) {
protected val testApp = PipAppHelper(instrumentation)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt
index 496fe94ba951..a3440df9ddf8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt
@@ -17,11 +17,10 @@
package com.android.wm.shell.flicker.splitscreen
import com.android.wm.shell.flicker.NonRotationTestBase
-import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_LABEL
-import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_COMPONENT_NAME
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_LABEL
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import com.android.wm.shell.flicker.testapp.Components
abstract class SplitScreenTestBase(
rotationName: String,
@@ -29,8 +28,8 @@ abstract class SplitScreenTestBase(
) : NonRotationTestBase(rotationName, rotation) {
protected val splitScreenApp = SplitScreenHelper(instrumentation,
TEST_APP_SPLITSCREEN_PRIMARY_LABEL,
- TEST_APP_SPLITSCREEN_PRIMARY_COMPONENT_NAME)
+ Components.SplitScreenActivity())
protected val secondaryApp = SplitScreenHelper(instrumentation,
TEST_APP_SPLITSCREEN_SECONDARY_LABEL,
- TEST_APP_SPLITSCREEN_SECONDARY_COMPONENT_NAME)
+ Components.SplitScreenSecondaryActivity())
}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp
index d12b49245277..26627a47ee62 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp
@@ -18,3 +18,9 @@ android_test {
sdk_version: "current",
test_suites: ["device-tests"],
}
+
+java_library {
+ name: "wmshell-flicker-test-components",
+ srcs: ["src/**/Components.java"],
+ sdk_version: "test_current",
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
index 628926a97bf5..a583b725899b 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -21,13 +21,25 @@
android:targetSdkVersion="29"/>
<application android:allowBackup="false"
android:supportsRtl="true">
+ <activity android:name=".FixedActivity"
+ android:resizeableActivity="true"
+ android:supportsPictureInPicture="true"
+ android:launchMode="singleTop"
+ android:label="FixedApp"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
<activity android:name=".PipActivity"
- android:resizeableActivity="true"
- android:supportsPictureInPicture="true"
- android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
- android:taskAffinity="com.android.wm.shell.flicker.testapp.PipActivity"
- android:label="PipApp"
- android:exported="true">
+ android:resizeableActivity="true"
+ android:supportsPictureInPicture="true"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
+ android:taskAffinity="com.android.wm.shell.flicker.testapp.PipActivity"
+ android:launchMode="singleTop"
+ android:label="PipApp"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@@ -39,9 +51,9 @@
</activity>
<activity android:name=".ImeActivity"
- android:taskAffinity="com.android.wm.shell.flicker.testapp.ImeActivity"
- android:label="ImeApp"
- android:exported="true">
+ android:taskAffinity="com.android.wm.shell.flicker.testapp.ImeActivity"
+ android:label="ImeApp"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
new file mode 100644
index 000000000000..8e9b4cb2d53e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.testapp;
+
+import android.content.ComponentName;
+
+public class Components {
+ public abstract static class ComponentsInfo {
+ public ComponentName getComponentName() {
+ return ComponentName.createRelative(PACKAGE_NAME, "." + getActivityName());
+ }
+ public abstract String getActivityName();
+ }
+
+ public static final String PACKAGE_NAME = "com.android.wm.shell.flicker.testapp";
+
+ public static class FixedActivity extends ComponentsInfo {
+ // Sets the fixed orientation (can be one of {@link ActivityInfo.ScreenOrientation}
+ public static final String EXTRA_FIXED_ORIENTATION = "fixed_orientation";
+
+ @Override
+ public String getActivityName() {
+ return FixedActivity.class.getSimpleName();
+ }
+ }
+
+ public static class PipActivity extends ComponentsInfo {
+ // Intent action that this activity dynamically registers to enter picture-in-picture
+ public static final String ACTION_ENTER_PIP = PACKAGE_NAME + ".PipActivity.ENTER_PIP";
+ // Intent action that this activity dynamically registers to set requested orientation.
+ // Will apply the oriention to the value set in the EXTRA_FIXED_ORIENTATION extra.
+ public static final String ACTION_SET_REQUESTED_ORIENTATION =
+ PACKAGE_NAME + ".PipActivity.SET_REQUESTED_ORIENTATION";
+
+ // Calls enterPictureInPicture() on creation
+ public static final String EXTRA_ENTER_PIP = "enter_pip";
+ // Sets the fixed orientation (can be one of {@link ActivityInfo.ScreenOrientation}
+ public static final String EXTRA_PIP_ORIENTATION = "fixed_orientation";
+ // Adds a click listener to finish this activity when it is clicked
+ public static final String EXTRA_TAP_TO_FINISH = "tap_to_finish";
+
+ @Override
+ public String getActivityName() {
+ return PipActivity.class.getSimpleName();
+ }
+ }
+
+ public static class ImeActivity extends ComponentsInfo {
+ @Override
+ public String getActivityName() {
+ return ImeActivity.class.getSimpleName();
+ }
+ }
+
+ public static class SplitScreenActivity extends ComponentsInfo {
+ @Override
+ public String getActivityName() {
+ return SplitScreenActivity.class.getSimpleName();
+ }
+ }
+
+ public static class SplitScreenSecondaryActivity extends ComponentsInfo {
+ @Override
+ public String getActivityName() {
+ return SplitScreenSecondaryActivity.class.getSimpleName();
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java
new file mode 100644
index 000000000000..d4ae6c1313bf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/FixedActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.testapp;
+
+import static com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION;
+
+import android.os.Bundle;
+
+public class FixedActivity extends SimpleActivity {
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Set the fixed orientation if requested
+ if (getIntent().hasExtra(EXTRA_FIXED_ORIENTATION)) {
+ final int ori = Integer.parseInt(getIntent().getStringExtra(EXTRA_FIXED_ORIENTATION));
+ setRequestedOrientation(ori);
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
index 909219583bf7..a6ba7823e22d 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
@@ -24,6 +24,11 @@ import static android.media.session.PlaybackState.STATE_PAUSED;
import static android.media.session.PlaybackState.STATE_PLAYING;
import static android.media.session.PlaybackState.STATE_STOPPED;
+import static com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP;
+import static com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_SET_REQUESTED_ORIENTATION;
+import static com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP;
+import static com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_PIP_ORIENTATION;
+
import android.app.Activity;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
@@ -32,12 +37,12 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.Configuration;
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.Bundle;
+import android.util.Log;
import android.util.Rational;
import android.view.View;
import android.view.Window;
@@ -50,6 +55,7 @@ import java.util.Collections;
import java.util.List;
public class PipActivity extends Activity {
+ private static final String TAG = PipActivity.class.getSimpleName();
/**
* A media session title for when the session is in {@link STATE_PLAYING}.
* TvPipNotificationTests check whether the actual notification title matches this string.
@@ -88,27 +94,43 @@ public class PipActivity extends Activity {
private final List<RemoteAction> mSwitchOffActions = new ArrayList<>();
private final List<RemoteAction> mSwitchOnActions = new ArrayList<>();
- private final BroadcastReceiver mCustomActionReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- switch (intent.getAction()) {
- case ACTION_SWITCH_ON:
- mPipParamsBuilder.setActions(mSwitchOnActions);
- break;
- case ACTION_SWITCH_OFF:
- mPipParamsBuilder.setActions(mSwitchOffActions);
- break;
- case ACTION_CLEAR:
- mPipParamsBuilder.setActions(Collections.emptyList());
- break;
- case ACTION_NO_OP:
- default:
- return;
+ if (isInPictureInPictureMode()) {
+ switch (intent.getAction()) {
+ case ACTION_SWITCH_ON:
+ mPipParamsBuilder.setActions(mSwitchOnActions);
+ break;
+ case ACTION_SWITCH_OFF:
+ mPipParamsBuilder.setActions(mSwitchOffActions);
+ break;
+ case ACTION_CLEAR:
+ mPipParamsBuilder.setActions(Collections.emptyList());
+ break;
+ case ACTION_NO_OP:
+ return;
+ default:
+ Log.w(TAG, "Unhandled action=" + intent.getAction());
+ return;
+ }
+ setPictureInPictureParams(mPipParamsBuilder.build());
+ } else {
+ switch (intent.getAction()) {
+ case ACTION_ENTER_PIP:
+ enterPip(null);
+ break;
+ case ACTION_SET_REQUESTED_ORIENTATION:
+ setRequestedOrientation(Integer.parseInt(intent.getStringExtra(
+ EXTRA_PIP_ORIENTATION)));
+ break;
+ default:
+ Log.w(TAG, "Unhandled action=" + intent.getAction());
+ return;
+ }
}
- setPictureInPictureParams(mPipParamsBuilder.build());
}
};
- private boolean mIsReceiverRegistered = false;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -160,36 +182,25 @@ public class PipActivity extends Activity {
final RemoteAction clearAllAction = buildRemoteAction(icon, PIP_ACTION_CLEAR, ACTION_CLEAR);
mSwitchOffActions.addAll(Arrays.asList(switchOnAction, clearAllAction));
mSwitchOnActions.addAll(Arrays.asList(noOpAction, switchOffAction, clearAllAction));
+
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_NO_OP);
+ filter.addAction(ACTION_SWITCH_ON);
+ filter.addAction(ACTION_SWITCH_OFF);
+ filter.addAction(ACTION_CLEAR);
+ filter.addAction(ACTION_SET_REQUESTED_ORIENTATION);
+ filter.addAction(ACTION_ENTER_PIP);
+ registerReceiver(mBroadcastReceiver, filter);
+
+ handleIntentExtra(getIntent());
}
@Override
protected void onDestroy() {
- if (mIsReceiverRegistered) {
- unregisterReceiver(mCustomActionReceiver);
- mIsReceiverRegistered = false;
- }
+ unregisterReceiver(mBroadcastReceiver);
super.onDestroy();
}
- @Override
- public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,
- Configuration newConfig) {
- if (isInPictureInPictureMode && !mIsReceiverRegistered) {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_NO_OP);
- filter.addAction(ACTION_SWITCH_ON);
- filter.addAction(ACTION_SWITCH_OFF);
- filter.addAction(ACTION_CLEAR);
- registerReceiver(mCustomActionReceiver, filter);
-
- mIsReceiverRegistered = true;
- } else if (!isInPictureInPictureMode && mIsReceiverRegistered) {
- unregisterReceiver(mCustomActionReceiver);
-
- mIsReceiverRegistered = false;
- }
- }
-
private RemoteAction buildRemoteAction(Icon icon, String label, String action) {
final Intent intent = new Intent(action);
final PendingIntent pendingIntent =
@@ -254,4 +265,17 @@ public class PipActivity extends Activity {
mMediaSession.setMetadata(mMediaMetadataBuilder.build());
mMediaSession.setActive(newState != STATE_STOPPED);
}
+
+ private void handleIntentExtra(Intent intent) {
+ // Set the fixed orientation if requested
+ if (intent.hasExtra(EXTRA_PIP_ORIENTATION)) {
+ final int ori = Integer.parseInt(getIntent().getStringExtra(EXTRA_PIP_ORIENTATION));
+ setRequestedOrientation(ori);
+ }
+ // Enter picture in picture with the given aspect ratio if provided
+ if (intent.hasExtra(EXTRA_ENTER_PIP)) {
+ mPipParamsBuilder.setActions(mSwitchOnActions);
+ enterPip(null);
+ }
+ }
}
diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in
index 49817925d9b4..c6c4ba8a6493 100644
--- a/libs/hwui/DisplayListOps.in
+++ b/libs/hwui/DisplayListOps.in
@@ -19,7 +19,6 @@ X(Save)
X(Restore)
X(SaveLayer)
X(SaveBehind)
-X(Concat44)
X(Concat)
X(SetMatrix)
X(Scale)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 473dc53dc4bf..a495ec4ac411 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -125,24 +125,18 @@ struct SaveBehind final : Op {
}
};
-struct Concat44 final : Op {
- static const auto kType = Type::Concat44;
- Concat44(const SkM44& m) : matrix(m) {}
- SkM44 matrix;
- void draw(SkCanvas* c, const SkMatrix&) const { c->concat(matrix); }
-};
struct Concat final : Op {
static const auto kType = Type::Concat;
- Concat(const SkMatrix& matrix) : matrix(matrix) {}
- SkMatrix matrix;
+ Concat(const SkM44& matrix) : matrix(matrix) {}
+ SkM44 matrix;
void draw(SkCanvas* c, const SkMatrix&) const { c->concat(matrix); }
};
struct SetMatrix final : Op {
static const auto kType = Type::SetMatrix;
- SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
- SkMatrix matrix;
+ SetMatrix(const SkM44& matrix) : matrix(matrix) {}
+ SkM44 matrix;
void draw(SkCanvas* c, const SkMatrix& original) const {
- c->setMatrix(SkMatrix::Concat(original, matrix));
+ c->setMatrix(SkM44(original) * matrix);
}
};
struct Scale final : Op {
@@ -569,12 +563,9 @@ void DisplayListData::saveBehind(const SkRect* subset) {
}
void DisplayListData::concat(const SkM44& m) {
- this->push<Concat44>(0, m);
-}
-void DisplayListData::concat(const SkMatrix& matrix) {
- this->push<Concat>(0, matrix);
+ this->push<Concat>(0, m);
}
-void DisplayListData::setMatrix(const SkMatrix& matrix) {
+void DisplayListData::setMatrix(const SkM44& matrix) {
this->push<SetMatrix>(0, matrix);
}
void DisplayListData::scale(SkScalar sx, SkScalar sy) {
@@ -834,10 +825,7 @@ bool RecordingCanvas::onDoSaveBehind(const SkRect* subset) {
void RecordingCanvas::didConcat44(const SkM44& m) {
fDL->concat(m);
}
-void RecordingCanvas::didConcat(const SkMatrix& matrix) {
- fDL->concat(matrix);
-}
-void RecordingCanvas::didSetMatrix(const SkMatrix& matrix) {
+void RecordingCanvas::didSetM44(const SkM44& matrix) {
fDL->setMatrix(matrix);
}
void RecordingCanvas::didScale(SkScalar sx, SkScalar sy) {
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 63d120c4ca19..4851148cd4d8 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -82,8 +82,7 @@ private:
void restore();
void concat(const SkM44&);
- void concat(const SkMatrix&);
- void setMatrix(const SkMatrix&);
+ void setMatrix(const SkM44&);
void scale(SkScalar, SkScalar);
void translate(SkScalar, SkScalar);
void translateZ(SkScalar);
@@ -154,8 +153,7 @@ public:
void onFlush() override;
void didConcat44(const SkM44&) override;
- void didConcat(const SkMatrix&) override;
- void didSetMatrix(const SkMatrix&) override;
+ void didSetM44(const SkM44&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 68541b4b31f0..671c66f11e32 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -26,6 +26,35 @@
namespace android::uirenderer {
+namespace {
+class ScopedCurrentFunctor {
+public:
+ ScopedCurrentFunctor(WebViewFunctor* functor) {
+ ALOG_ASSERT(!sCurrentFunctor);
+ ALOG_ASSERT(functor);
+ sCurrentFunctor = functor;
+ }
+ ~ScopedCurrentFunctor() {
+ ALOG_ASSERT(sCurrentFunctor);
+ sCurrentFunctor = nullptr;
+ }
+
+ static ASurfaceControl* getSurfaceControl() {
+ ALOG_ASSERT(sCurrentFunctor);
+ return sCurrentFunctor->getSurfaceControl();
+ }
+ static void mergeTransaction(ASurfaceTransaction* transaction) {
+ ALOG_ASSERT(sCurrentFunctor);
+ sCurrentFunctor->mergeTransaction(transaction);
+ }
+
+private:
+ static WebViewFunctor* sCurrentFunctor;
+};
+
+WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr;
+} // namespace
+
RenderMode WebViewFunctor_queryPlatformRenderMode() {
auto pipelineType = Properties::getRenderPipelineType();
switch (pipelineType) {
@@ -83,7 +112,15 @@ void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
if (!mHasContext) {
mHasContext = true;
}
- mCallbacks.gles.draw(mFunctor, mData, drawInfo);
+ ScopedCurrentFunctor currentFunctor(this);
+
+ WebViewOverlayData overlayParams = {
+ // TODO:
+ .overlaysMode = OverlaysMode::Disabled,
+ .getSurfaceControl = currentFunctor.getSurfaceControl,
+ .mergeTransaction = currentFunctor.mergeTransaction,
+ };
+ mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
}
void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
@@ -98,7 +135,15 @@ void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
ATRACE_NAME("WebViewFunctor::drawVk");
- mCallbacks.vk.draw(mFunctor, mData, params);
+ ScopedCurrentFunctor currentFunctor(this);
+
+ WebViewOverlayData overlayParams = {
+ // TODO
+ .overlaysMode = OverlaysMode::Disabled,
+ .getSurfaceControl = currentFunctor.getSurfaceControl,
+ .mergeTransaction = currentFunctor.mergeTransaction,
+ };
+ mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
}
void WebViewFunctor::postDrawVk() {
@@ -118,6 +163,20 @@ void WebViewFunctor::destroyContext() {
}
}
+void WebViewFunctor::removeOverlays() {
+ ScopedCurrentFunctor currentFunctor(this);
+ mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
+}
+
+ASurfaceControl* WebViewFunctor::getSurfaceControl() {
+ // TODO
+ return nullptr;
+}
+
+void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
+ // TODO
+}
+
WebViewFunctorManager& WebViewFunctorManager::instance() {
static WebViewFunctorManager sInstance;
return sInstance;
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 675b738c6406..737d60525aa9 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -56,6 +56,8 @@ public:
void postDrawVk() { mReference.postDrawVk(); }
+ void removeOverlays() { mReference.removeOverlays(); }
+
private:
friend class WebViewFunctor;
@@ -71,6 +73,10 @@ public:
void drawVk(const VkFunctorDrawParams& params);
void postDrawVk();
void destroyContext();
+ void removeOverlays();
+
+ ASurfaceControl* getSurfaceControl();
+ void mergeTransaction(ASurfaceTransaction* transaction);
sp<Handle> createHandle() {
LOG_ALWAYS_FATAL_IF(mCreatedHandle);
diff --git a/libs/hwui/jni/pdf/PdfEditor.cpp b/libs/hwui/jni/pdf/PdfEditor.cpp
index e65921ac8e0a..427bafa1bd83 100644
--- a/libs/hwui/jni/pdf/PdfEditor.cpp
+++ b/libs/hwui/jni/pdf/PdfEditor.cpp
@@ -129,8 +129,8 @@ static void nativeSetTransformAndClip(JNIEnv* env, jclass thiz, jlong documentPt
// PDF's coordinate system origin is left-bottom while in graphics it
// is the top-left. So, translate the PDF coordinates to ours.
- SkMatrix reflectOnX = SkMatrix::MakeScale(1, -1);
- SkMatrix moveUp = SkMatrix::MakeTrans(0, FPDF_GetPageHeight(page));
+ SkMatrix reflectOnX = SkMatrix::Scale(1, -1);
+ SkMatrix moveUp = SkMatrix::Translate(0, FPDF_GetPageHeight(page));
SkMatrix coordinateChange = SkMatrix::Concat(moveUp, reflectOnX);
// Apply the transformation what was created in our coordinates.
diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h
index 96da947ace08..22ae59e5137b 100644
--- a/libs/hwui/private/hwui/WebViewFunctor.h
+++ b/libs/hwui/private/hwui/WebViewFunctor.h
@@ -17,6 +17,15 @@
#ifndef FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
#define FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
+#ifdef __ANDROID__ // Layoutlib does not support surface control
+#include <android/surface_control.h>
+#else
+// To avoid ifdefs around overlay implementation all over the place we typedef these to void *. They
+// won't be used.
+typedef void* ASurfaceControl;
+typedef void* ASurfaceTransaction;
+#endif
+
#include <cutils/compiler.h>
#include <private/hwui/DrawGlInfo.h>
#include <private/hwui/DrawVkInfo.h>
@@ -28,6 +37,14 @@ enum class RenderMode {
Vulkan,
};
+enum class OverlaysMode {
+ // Indicated that webview should not promote anything to overlays this draw
+ // and remove all visible overlays.
+ Disabled,
+ // Indicates that webview can use overlays.
+ Enabled
+};
+
// Static for the lifetime of the process
ANDROID_API RenderMode WebViewFunctor_queryPlatformRenderMode();
@@ -35,6 +52,23 @@ struct WebViewSyncData {
bool applyForceDark;
};
+struct WebViewOverlayData {
+ // Desired overlay mode for this draw.
+ OverlaysMode overlaysMode;
+
+ // Returns parent ASurfaceControl for WebView overlays. It will be have same
+ // geometry as the surface we draw into and positioned below it (underlay).
+ // This does not pass ownership to webview, but guaranteed to be alive until
+ // transaction from next removeOverlays call or functor destruction will be
+ // finished.
+ ASurfaceControl* (*getSurfaceControl)();
+
+ // Merges WebView transaction to be applied synchronously with current draw.
+ // This doesn't pass ownership of the transaction, changes will be copied and
+ // webview can free transaction right after the call.
+ void (*mergeTransaction)(ASurfaceTransaction*);
+};
+
struct WebViewFunctorCallbacks {
// kModeSync, called on RenderThread
void (*onSync)(int functor, void* data, const WebViewSyncData& syncData);
@@ -48,16 +82,23 @@ struct WebViewFunctorCallbacks {
// this functor had ever been drawn.
void (*onDestroyed)(int functor, void* data);
+ // Called on render thread to force webview hide all overlays and stop updating them.
+ // Should happen during hwui draw (e.g can be called instead of draw if webview
+ // isn't visible and won't receive draw) and support MergeTransaction call.
+ void (*removeOverlays)(int functor, void* data, void (*mergeTransaction)(ASurfaceTransaction*));
+
union {
struct {
// Called on RenderThread. initialize is guaranteed to happen before this call
- void (*draw)(int functor, void* data, const DrawGlInfo& params);
+ void (*draw)(int functor, void* data, const DrawGlInfo& params,
+ const WebViewOverlayData& overlayParams);
} gles;
struct {
// Called either the first time the functor is used or the first time it's used after
// a call to onContextDestroyed.
void (*initialize)(int functor, void* data, const VkFunctorInitParams& params);
- void (*draw)(int functor, void* data, const VkFunctorDrawParams& params);
+ void (*draw)(int functor, void* data, const VkFunctorDrawParams& params,
+ const WebViewOverlayData& overlayParams);
void (*postDraw)(int functor, void*);
} vk;
};
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 36c5a8c1b3de..c1d8b761514b 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -323,7 +323,8 @@ public:
};
switch (mode) {
case RenderMode::OpenGL_ES:
- callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) {
+ callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params,
+ const WebViewOverlayData& overlay_params) {
expectOnRenderThread("draw");
sMockFunctorCounts[functor].glesDraw++;
};
diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
index f4c3e13b0ea6..955a5e7d8b3a 100644
--- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
+++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
@@ -39,7 +39,7 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) {
EXPECT_EQ(Matrix4::identity(), layerUpdater->backingLayer()->getTexTransform());
// push the deferred updates to the layer
- SkMatrix scaledMatrix = SkMatrix::MakeScale(0.5, 0.5);
+ SkMatrix scaledMatrix = SkMatrix::Scale(0.5, 0.5);
SkBitmap bitmap;
bitmap.allocN32Pixels(16, 16);
sk_sp<SkImage> layerImage = SkImage::MakeFromBitmap(bitmap);
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index abdf9d587189..26bc65915c7a 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -206,7 +206,7 @@ TEST(RenderNodeDrawable, saveLayerClipAndMatrixRestore) {
ASSERT_EQ(SkRect::MakeLTRB(50, 50, 350, 350), getRecorderClipBounds(recorder));
recorder.translate(300.0f, 400.0f);
- EXPECT_EQ(SkMatrix::MakeTrans(300.0f, 400.0f), getRecorderMatrix(recorder));
+ EXPECT_EQ(SkMatrix::Translate(300.0f, 400.0f), getRecorderMatrix(recorder));
recorder.restore();
ASSERT_EQ(SkRect::MakeLTRB(0, 0, 400, 800), getRecorderClipBounds(recorder));
@@ -1107,27 +1107,27 @@ TEST(ReorderBarrierDrawable, testShadowMatrix) {
EXPECT_EQ(dy, TRANSLATE_Y);
}
- virtual void didSetMatrix(const SkMatrix& matrix) override {
+ virtual void didSetM44(const SkM44& matrix) override {
mDrawCounter++;
// First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix.
// Second invocation is preparing the matrix for an elevated RenderNodeDrawable.
- EXPECT_TRUE(matrix.isIdentity());
+ EXPECT_TRUE(matrix == SkM44());
EXPECT_TRUE(getTotalMatrix().isIdentity());
}
- virtual void didConcat(const SkMatrix& matrix) override {
+ virtual void didConcat44(const SkM44& matrix) override {
mDrawCounter++;
if (mFirstDidConcat) {
// First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix.
mFirstDidConcat = false;
- EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
+ EXPECT_EQ(SkM44::Translate(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
matrix);
- EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
+ EXPECT_EQ(SkMatrix::Translate(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
getTotalMatrix());
} else {
// Second invocation is preparing the matrix for an elevated RenderNodeDrawable.
- EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y), matrix);
- EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y), getTotalMatrix());
+ EXPECT_EQ(SkM44::Translate(TRANSLATE_X, TRANSLATE_Y), matrix);
+ EXPECT_EQ(SkMatrix::Translate(TRANSLATE_X, TRANSLATE_Y), getTotalMatrix());
}
}
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index 74a565439f85..2d34b0980546 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -263,10 +263,10 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren_vdOffscr
}
// Another way to be offscreen: a matrix from the draw call.
- for (const SkMatrix translate : { SkMatrix::MakeTrans(width, 0),
- SkMatrix::MakeTrans(0, height),
- SkMatrix::MakeTrans(-width, 0),
- SkMatrix::MakeTrans(0, -height)}) {
+ for (const SkMatrix translate : { SkMatrix::Translate(width, 0),
+ SkMatrix::Translate(0, height),
+ SkMatrix::Translate(-width, 0),
+ SkMatrix::Translate(0, -height)}) {
SkiaDisplayList skiaDL;
VectorDrawableRoot dirtyVD(new VectorDrawable::Group());
dirtyVD.mutateProperties()->setBounds(bounds);
@@ -291,7 +291,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren_vdOffscr
SkiaDisplayList skiaDL;
VectorDrawableRoot dirtyVD(new VectorDrawable::Group());
dirtyVD.mutateProperties()->setBounds(bounds);
- SkMatrix translate = SkMatrix::MakeTrans(50, 50);
+ SkMatrix translate = SkMatrix::Translate(50, 50);
skiaDL.appendVD(&dirtyVD, translate);
ASSERT_TRUE(dirtyVD.isDirty());
diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
index eec25c6bd40d..15ecf5831f3a 100644
--- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
+++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
@@ -111,11 +111,11 @@ TEST(RenderNodeDrawable, renderPropTransform) {
[](RenderProperties& properties) {
properties.setLeftTopRightBottom(10, 10, 110, 110);
- SkMatrix staticMatrix = SkMatrix::MakeScale(1.2f, 1.2f);
+ SkMatrix staticMatrix = SkMatrix::Scale(1.2f, 1.2f);
properties.setStaticMatrix(&staticMatrix);
// ignored, since static overrides animation
- SkMatrix animationMatrix = SkMatrix::MakeTrans(15, 15);
+ SkMatrix animationMatrix = SkMatrix::Translate(15, 15);
properties.setAnimationMatrix(&animationMatrix);
properties.setTranslationX(10);
diff --git a/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java b/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java
index 7eb843e93e68..31c27d1bb977 100644
--- a/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java
+++ b/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java
@@ -24,6 +24,7 @@ import android.os.Parcelable;
import com.android.internal.util.Preconditions;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -70,30 +71,30 @@ public final class LocationTimeZoneEvent implements Parcelable {
@NonNull
private final List<String> mTimeZoneIds;
- private final long mElapsedRealtimeNanos;
+ private final long mElapsedRealtimeMillis;
private LocationTimeZoneEvent(@EventType int eventType, @NonNull List<String> timeZoneIds,
- long elapsedRealtimeNanos) {
+ long elapsedRealtimeMillis) {
mEventType = checkValidEventType(eventType);
mTimeZoneIds = immutableList(timeZoneIds);
boolean emptyTimeZoneIdListExpected = eventType != EVENT_TYPE_SUCCESS;
Preconditions.checkState(!emptyTimeZoneIdListExpected || timeZoneIds.isEmpty());
- mElapsedRealtimeNanos = elapsedRealtimeNanos;
+ mElapsedRealtimeMillis = elapsedRealtimeMillis;
}
/**
* Returns the time of this fix, in elapsed real-time since system boot.
*
* <p>This value can be reliably compared to {@link
- * android.os.SystemClock#elapsedRealtimeNanos}, to calculate the age of a fix and to compare
+ * android.os.SystemClock#elapsedRealtime()}, to calculate the age of a fix and to compare
* {@link LocationTimeZoneEvent} instances.
*
- * @return elapsed real-time of fix, in nanoseconds since system boot.
+ * @return elapsed real-time of fix, in milliseconds
*/
- public long getElapsedRealtimeNanos() {
- return mElapsedRealtimeNanos;
+ public long getElapsedRealtimeMillis() {
+ return mElapsedRealtimeMillis;
}
/**
@@ -118,7 +119,8 @@ public final class LocationTimeZoneEvent implements Parcelable {
return "LocationTimeZoneEvent{"
+ "mEventType=" + mEventType
+ ", mTimeZoneIds=" + mTimeZoneIds
- + ", mElapsedRealtimeNanos=" + mElapsedRealtimeNanos
+ + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
+ + "(" + Duration.ofMillis(mElapsedRealtimeMillis) + ")"
+ '}';
}
@@ -130,8 +132,8 @@ public final class LocationTimeZoneEvent implements Parcelable {
@SuppressWarnings("unchecked")
ArrayList<String> timeZoneIds =
(ArrayList<String>) in.readArrayList(null /* classLoader */);
- long elapsedRealtimeNanos = in.readLong();
- return new LocationTimeZoneEvent(eventType, timeZoneIds, elapsedRealtimeNanos);
+ long elapsedRealtimeMillis = in.readLong();
+ return new LocationTimeZoneEvent(eventType, timeZoneIds, elapsedRealtimeMillis);
}
@Override
@@ -149,7 +151,7 @@ public final class LocationTimeZoneEvent implements Parcelable {
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mEventType);
parcel.writeList(mTimeZoneIds);
- parcel.writeLong(mElapsedRealtimeNanos);
+ parcel.writeLong(mElapsedRealtimeMillis);
}
@Override
@@ -162,13 +164,13 @@ public final class LocationTimeZoneEvent implements Parcelable {
}
LocationTimeZoneEvent that = (LocationTimeZoneEvent) o;
return mEventType == that.mEventType
- && mElapsedRealtimeNanos == that.mElapsedRealtimeNanos
+ && mElapsedRealtimeMillis == that.mElapsedRealtimeMillis
&& mTimeZoneIds.equals(that.mTimeZoneIds);
}
@Override
public int hashCode() {
- return Objects.hash(mEventType, mTimeZoneIds, mElapsedRealtimeNanos);
+ return Objects.hash(mEventType, mTimeZoneIds, mElapsedRealtimeMillis);
}
/** @hide */
@@ -176,7 +178,7 @@ public final class LocationTimeZoneEvent implements Parcelable {
private @EventType int mEventType = EVENT_TYPE_UNKNOWN;
private @NonNull List<String> mTimeZoneIds = Collections.emptyList();
- private long mElapsedRealtimeNanos;
+ private long mElapsedRealtimeMillis;
public Builder() {
}
@@ -187,7 +189,7 @@ public final class LocationTimeZoneEvent implements Parcelable {
public Builder(@NonNull LocationTimeZoneEvent ltz) {
mEventType = ltz.mEventType;
mTimeZoneIds = ltz.mTimeZoneIds;
- mElapsedRealtimeNanos = ltz.mElapsedRealtimeNanos;
+ mElapsedRealtimeMillis = ltz.mElapsedRealtimeMillis;
}
/**
@@ -210,8 +212,8 @@ public final class LocationTimeZoneEvent implements Parcelable {
/**
* Sets the time of this event, in elapsed real-time since system boot.
*/
- public Builder setElapsedRealtimeNanos(long time) {
- mElapsedRealtimeNanos = time;
+ public Builder setElapsedRealtimeMillis(long time) {
+ mElapsedRealtimeMillis = time;
return this;
}
@@ -219,7 +221,7 @@ public final class LocationTimeZoneEvent implements Parcelable {
* Builds a {@link LocationTimeZoneEvent} instance.
*/
public LocationTimeZoneEvent build() {
- return new LocationTimeZoneEvent(mEventType, mTimeZoneIds, mElapsedRealtimeNanos);
+ return new LocationTimeZoneEvent(mEventType, mTimeZoneIds, mElapsedRealtimeMillis);
}
}
diff --git a/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java b/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java
index d044c0b52939..55f554554474 100644
--- a/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java
+++ b/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java
@@ -147,7 +147,7 @@ public final class LocationTimeZoneEventUnbundled {
LocationTimeZoneEvent event = new LocationTimeZoneEvent.Builder()
.setEventType(internalEventType)
.setTimeZoneIds(mTimeZoneIds)
- .setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos())
+ .setElapsedRealtimeMillis(SystemClock.elapsedRealtime())
.build();
return new LocationTimeZoneEventUnbundled(event);
}
diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h
index 42cad43af8fc..44fe56fcaf4b 100644
--- a/native/webview/plat_support/draw_fn.h
+++ b/native/webview/plat_support/draw_fn.h
@@ -10,6 +10,7 @@
#ifndef ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_FN_H_
#define ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_FN_H_
+#include <android/surface_control.h>
#include <vulkan/vulkan.h>
#ifdef __cplusplus
@@ -21,7 +22,31 @@ extern "C" {
//
// 1 is Android Q. This matches kAwDrawGLInfoVersion version 3.
// 2 Adds transfer_function_* and color_space_toXYZD50 to AwDrawFn_DrawGLParams.
-static const int kAwDrawFnVersion = 2;
+// 3 Adds SurfaceControl related functions.
+static const int kAwDrawFnVersion = 3;
+
+// Returns parent ASurfaceControl for WebView overlays. It will be have same
+// geometry as the surface we draw into and positioned below it (underlay).
+// This does not pass ownership to webview, but guaranteed to be alive until
+// transaction from next removeOverlays call or functor destruction will be
+// finished.
+typedef ASurfaceControl* AwDrawFn_GetSurfaceControl();
+
+// Merges WebView transaction to be applied synchronously with current draw.
+// This doesn't pass ownership of the transaction, changes will be copied and
+// webview can free transaction right after the call.
+typedef void AwDrawFn_MergeTransaction(ASurfaceTransaction* transaction);
+
+enum AwDrawFnOverlaysMode {
+ // Indicated that webview should not promote anything to overlays this draw
+ // and remove all visible overlays.
+ // Added in version 3.
+ AW_DRAW_FN_OVERLAYS_MODE_DISABLED = 0,
+
+ // Indicates that webview can use overlays.
+ // Added in version 3.
+ AW_DRAW_FN_OVERLAYS_MODE_ENABLED = 1,
+};
struct AwDrawFn_OnSyncParams {
int version;
@@ -60,6 +85,19 @@ struct AwDrawFn_DrawGLParams {
float transfer_function_e;
float transfer_function_f;
float color_space_toXYZD50[9];
+
+ // Input: Indicates how webview should use overlays for this draw.
+ // Added in version 3.
+ AwDrawFnOverlaysMode overlays_mode;
+
+ // Input: WebView can call it to obtain parent surface control for overlays.
+ // Added in version 3.
+ AwDrawFn_GetSurfaceControl* get_surface_control;
+
+ // Input: WebView call this to apply ASurfaceTransaction synchronously with
+ // the draw.
+ // Added in version 3.
+ AwDrawFn_MergeTransaction* merge_transaction;
};
struct AwDrawFn_InitVkParams {
@@ -122,12 +160,33 @@ struct AwDrawFn_DrawVkParams {
int clip_top;
int clip_right;
int clip_bottom;
+
+ // Input: Indicates how webview should use overlays for this draw.
+ // Added in version 3.
+ AwDrawFnOverlaysMode overlays_mode;
+
+ // Input: WebView can call it to obtain parent surface control for overlays.
+ // Added in version 3.
+ AwDrawFn_GetSurfaceControl* get_surface_control;
+
+ // Input: WebView call this to apply ASurfaceTransaction synchronously with
+ // the draw.
+ // Added in version 3.
+ AwDrawFn_MergeTransaction* merge_transaction;
};
struct AwDrawFn_PostDrawVkParams {
int version;
};
+struct AwDrawFn_RemoveOverlaysParams {
+ int version;
+ // Input: WebView call this to apply ASurfaceTransaction synchronously with
+ // the draw.
+ // Added in version 3.
+ AwDrawFn_MergeTransaction* merge_transaction;
+};
+
// Called on render thread while UI thread is blocked. Called for both GL and
// VK.
typedef void AwDrawFn_OnSync(int functor,
@@ -166,8 +225,15 @@ typedef void AwDrawFn_PostDrawVk(int functor,
void* data,
AwDrawFn_PostDrawVkParams* params);
+// Can be called to make webview hide all overlays and stop updating them until
+// next draw. WebView must obtain new ASurfaceControl after this call to use as
+// parent for the overlays on next draw.
+typedef void AwDrawFn_RemoveOverlays(int functor,
+ void* data,
+ AwDrawFn_RemoveOverlaysParams* params);
+
struct AwDrawFnFunctorCallbacks {
- // No version here since this is passed from chromium to android.
+ // version is passed in CreateFunctor call.
AwDrawFn_OnSync* on_sync;
AwDrawFn_OnContextDestroyed* on_context_destroyed;
AwDrawFn_OnDestroyed* on_destroyed;
@@ -175,6 +241,8 @@ struct AwDrawFnFunctorCallbacks {
AwDrawFn_InitVk* init_vk;
AwDrawFn_DrawVk* draw_vk;
AwDrawFn_PostDrawVk* post_draw_vk;
+ // Added in version 3.
+ AwDrawFn_RemoveOverlays* remove_overlays;
};
enum AwDrawFnRenderMode {
@@ -185,10 +253,16 @@ enum AwDrawFnRenderMode {
// Get the render mode. Result is static for the process.
typedef AwDrawFnRenderMode AwDrawFn_QueryRenderMode(void);
-// Create a functor. |functor_callbacks| should be valid until OnDestroyed.
+// This available up to version 3, use the one below.
typedef int AwDrawFn_CreateFunctor(void* data,
AwDrawFnFunctorCallbacks* functor_callbacks);
+// Create a functor. |functor_callbacks| should be valid until OnDestroyed.
+typedef int AwDrawFn_CreateFunctor_v3(
+ void* data,
+ int version,
+ AwDrawFnFunctorCallbacks* functor_callbacks);
+
// May be called on any thread to signal that the functor should be destroyed.
// The functor will receive an onDestroyed when the last usage of it is
// released, and it should be considered alive & active until that point.
@@ -197,8 +271,11 @@ typedef void AwDrawFn_ReleaseFunctor(int functor);
struct AwDrawFnFunctionTable {
int version;
AwDrawFn_QueryRenderMode* query_render_mode;
+ // Available up to version 3.
AwDrawFn_CreateFunctor* create_functor;
AwDrawFn_ReleaseFunctor* release_functor;
+ // Added in version 3.
+ AwDrawFn_CreateFunctor_v3* create_functor_v3;
};
#ifdef __cplusplus
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index 7cce61b87d12..ea57ea070369 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -32,6 +32,15 @@ struct SupportData {
AwDrawFnFunctorCallbacks callbacks;
};
+AwDrawFnOverlaysMode GetOverlaysMode(uirenderer::OverlaysMode overlays_mode) {
+ switch (overlays_mode) {
+ case uirenderer::OverlaysMode::Disabled:
+ return AW_DRAW_FN_OVERLAYS_MODE_DISABLED;
+ case uirenderer::OverlaysMode::Enabled:
+ return AW_DRAW_FN_OVERLAYS_MODE_ENABLED;
+ }
+}
+
void onSync(int functor, void* data,
const uirenderer::WebViewSyncData& syncData) {
AwDrawFn_OnSyncParams params = {
@@ -53,8 +62,20 @@ void onDestroyed(int functor, void* data) {
delete support;
}
+void removeOverlays(int functor, void* data,
+ AwDrawFn_MergeTransaction merge_transaction) {
+ AwDrawFn_RemoveOverlaysParams params = {
+ .version = kAwDrawFnVersion,
+ .merge_transaction = merge_transaction
+ };
+ SupportData* support = static_cast<SupportData*>(data);
+ if (support->callbacks.remove_overlays)
+ support->callbacks.remove_overlays(functor, support->data, &params);
+}
+
void draw_gl(int functor, void* data,
- const uirenderer::DrawGlInfo& draw_gl_params) {
+ const uirenderer::DrawGlInfo& draw_gl_params,
+ const uirenderer::WebViewOverlayData& overlay_params) {
float gabcdef[7];
draw_gl_params.color_space_ptr->transferFn(gabcdef);
AwDrawFn_DrawGLParams params = {
@@ -73,6 +94,9 @@ void draw_gl(int functor, void* data,
.transfer_function_d = gabcdef[4],
.transfer_function_e = gabcdef[5],
.transfer_function_f = gabcdef[6],
+ .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode),
+ .get_surface_control = overlay_params.getSurfaceControl,
+ .merge_transaction = overlay_params.mergeTransaction
};
COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform),
mismatched_transform_matrix_sizes);
@@ -118,7 +142,9 @@ void initializeVk(int functor, void* data,
support->callbacks.init_vk(functor, support->data, &params);
}
-void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw_vk_params) {
+void drawVk(int functor, void* data,
+ const uirenderer::VkFunctorDrawParams& draw_vk_params,
+ const uirenderer::WebViewOverlayData& overlay_params) {
SupportData* support = static_cast<SupportData*>(data);
float gabcdef[7];
draw_vk_params.color_space_ptr->transferFn(gabcdef);
@@ -142,6 +168,9 @@ void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw
.clip_top = draw_vk_params.clip_top,
.clip_right = draw_vk_params.clip_right,
.clip_bottom = draw_vk_params.clip_bottom,
+ .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode),
+ .get_surface_control = overlay_params.getSurfaceControl,
+ .merge_transaction = overlay_params.mergeTransaction
};
COMPILE_ASSERT(sizeof(params.color_space_toXYZD50) == sizeof(skcms_Matrix3x3),
gamut_transform_size_mismatch);
@@ -161,12 +190,14 @@ void postDrawVk(int functor, void* data) {
support->callbacks.post_draw_vk(functor, support->data, &params);
}
-int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
+int CreateFunctor_v3(void* data, int version,
+ AwDrawFnFunctorCallbacks* functor_callbacks) {
static bool callbacks_initialized = false;
static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = {
.onSync = &onSync,
.onContextDestroyed = &onContextDestroyed,
.onDestroyed = &onDestroyed,
+ .removeOverlays = &removeOverlays,
};
if (!callbacks_initialized) {
switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
@@ -183,8 +214,23 @@ int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
}
SupportData* support = new SupportData{
.data = data,
- .callbacks = *functor_callbacks,
};
+
+ // These callbacks are available on all versions.
+ support->callbacks = {
+ .on_sync = functor_callbacks->on_sync,
+ .on_context_destroyed = functor_callbacks->on_context_destroyed,
+ .on_destroyed = functor_callbacks->on_destroyed,
+ .draw_gl = functor_callbacks->draw_gl,
+ .init_vk = functor_callbacks->init_vk,
+ .draw_vk = functor_callbacks->draw_vk,
+ .post_draw_vk = functor_callbacks->post_draw_vk,
+ };
+
+ if (version >= 3) {
+ support->callbacks.remove_overlays = functor_callbacks->remove_overlays;
+ }
+
int functor = uirenderer::WebViewFunctor_create(
support, webview_functor_callbacks,
uirenderer::WebViewFunctor_queryPlatformRenderMode());
@@ -192,6 +238,12 @@ int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
return functor;
}
+int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
+ const int kVersionForDeprecatedCreateFunctor = 2;
+ return CreateFunctor_v3(data, kVersionForDeprecatedCreateFunctor,
+ functor_callbacks);
+}
+
void ReleaseFunctor(int functor) {
uirenderer::WebViewFunctor_release(functor);
}
@@ -211,6 +263,7 @@ jlong GetDrawFnFunctionTable() {
.query_render_mode = &QueryRenderMode,
.create_functor = &CreateFunctor,
.release_functor = &ReleaseFunctor,
+ .create_functor_v3 = &CreateFunctor_v3,
};
return reinterpret_cast<intptr_t>(&function_table);
}
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 2b30e0a61863..41af185da0b7 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> oor tot battery gelaai is"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot battery gelaai is"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Battery word tydelik beperk"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Laai"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laai tans vinnig"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 0bebfabf2eb9..8e4e402c2e16 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ኃይል እስከሚሞላ ድረስ ይቀራል"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ኃይል እስከሚሞላ ድረስ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ባትሪ ለጊዜው ተገድቧል"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ያልታወቀ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ኃይል በፍጥነት በመሙላት ላይ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 6eaf3a98da11..691ec046da02 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> إلى أن يتم شحن الجهاز بالكامل"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> إلى أن يتم شحن الجهاز بالكامل"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - تأثير محدود على البطارية مؤقتًا"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"غير معروف"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"جارٍ الشحن"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"جارٍ الشحن سريعًا"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index e207e1ce4c12..61214e09ba26 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"চাৰ্জ হ’বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> চাৰ্জ হ\'বলৈ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - বেটাৰী সাময়িকভাৱে সীমিত কৰা হৈছে"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"অজ্ঞাত"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"চাৰ্জ কৰি থকা হৈছে"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্ৰুততাৰে চাৰ্জ হৈছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index ff1209c754d1..db61527a54d8 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Enerjinin dolmasına <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - Enerjinin dolmasına <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batareya müvəqqəti məhdudlaşdırılıb"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Naməlum"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Enerji doldurma"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Sürətlə doldurulur"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index eb099c1926a7..70fb3636b492 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Napuniće se za <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – napuniće se za <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – baterija je trenutno ograničena"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Puni se"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo se puni"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index e6e49ab2063c..8a0db8261a71 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Засталося <xliff:g id="TIME">%1$s</xliff:g> да поўнай зарадкі"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарад акумулятара часова абмежаваны"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Невядома"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарадка"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хуткая зарадка"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 251c4dd545c4..27dcf105fd2e 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Батерията е временно ограничена"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарежда се"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Зарежда се бързо"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 6a99a84358d4..29862e6efd31 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -211,9 +211,9 @@
<string name="adb_wireless_error" msgid="721958772149779856">"সমস্যা"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"ওয়্যারলেস ডিবাগিং"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"কোন কোন ডিভাইস উপলভ্য আছে তা দেখে নিয়ে ব্যবহার করার জন্য, ওয়্যারলেস ডিবাগিং চালু করুন"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR কোড স্ক্যানার ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"যোগ করার কোড ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"পেয়ারিং কোড ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ছয় সংখ্যার কোড ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"যোগ করা ডিভাইস"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"এখন কানেক্ট রয়েছে"</string>
@@ -222,16 +222,16 @@
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"ডিভাইসে আঙ্গুলের ছাপ: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"কানেক্ট করা যায়নি"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>টি সঠিক নেটওয়ার্কে কানেক্ট আছে কিনা দেখে নিন"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"ডিভাইসের সাথে যোগ করুন"</string>
- <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"ওয়াই-ফাই যোগ করার কোড"</string>
- <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"যোগ করা যায়নি"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"ডিভাইসের সাথে পেয়ার করুন"</string>
+ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"ওয়াই-ফাইয়ের সাথে পেয়ার করার কোড"</string>
+ <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"পেয়ার করা যায়নি"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"ডিভাইসটি একই নেটওয়ার্কে কানেক্ট আছে কিনা দেখে নিন।"</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইস যোগ করুন"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"ডিভাইস যোগ করা হচ্ছে…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ডিভাইস যোগ করা যায়নি। এটি দুটি কারণে হয়ে থাকে - QR কোডটি সঠিক নয় বা ডিভাইসটি একই নেটওয়ার্কে কানেক্ট করা নেই।"</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP অ্যাড্রেস ও পোর্ট"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR কোড স্ক্যান করুন"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR কোড স্ক্যান করে ওয়াই-ফাইয়ের সাহায্যে ডিভাইস যোগ করুন"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইসের সাথে পেয়ার করুন"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"একটি ওয়াই-ফাই নেটওয়ার্কের সাথে কানেক্ট করুন"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"ত্রুটি প্রতিবেদনের শর্টকাট"</string>
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%1$s</xliff:g> বাকি আছে"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>-এ সম্পূর্ণ চার্জ হয়ে যাবে"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ব্যাটারি কিছুক্ষণের জন্য সীমিত করা হয়েছে"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"অজানা"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"চার্জ হচ্ছে"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্রুত চার্জ হচ্ছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index aeb7f2ecc567..4704ec8db79a 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Napunit će se za <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – napunit će se za <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Baterija je privremeno ograničena"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index df4c99e20505..5d04963d9b4a 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -66,7 +66,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconnectat"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"S\'està desconnectant..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"S\'està connectant…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connectat"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"S\'està vinculant..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense accés al telèfon)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense contingut multimèdia)"</string>
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g>: bateria limitada temporalment"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconegut"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"S\'està carregant"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregant ràpidament"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index e563ca5a03f8..a99a4dabbc60 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Do nabití zbývá: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do nabití"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Baterie dočasně omezena"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Neznámé"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíjí se"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rychlé nabíjení"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 8a3d054c3ae8..c90155eb2b68 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Batteriet er midlertidigt begrænset"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ukendt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Oplader"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Oplader hurtigt"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 624b299a96c3..b5b9fc480607 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Inaktiv. Zum Wechseln tippen."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktiv. Zum Wechseln tippen."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Standby-Status der App:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"Einstellungen für Medientranscodierung"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"Transcodierung deaktivieren"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"Transcodierung für Apps aktivieren"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Aktive Dienste"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"Momentan ausgeführte Dienste anzeigen und steuern"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-Implementierung"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Noch <xliff:g id="TIME">%1$s</xliff:g> bis zur Aufladung"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis zur Aufladung"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Akku vorübergehend eingeschränkt"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unbekannt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Wird aufgeladen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Schnelles Aufladen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 7ea90506ac06..203ec40c5a42 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> για ολοκλήρωση της φόρτισης"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για την ολοκλήρωση της φόρτισης"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Η μπαταρία περιορίστηκε προσωρινά."</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Άγνωστο"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Φόρτιση"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ταχεία φόρτιση"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 7affb5c89dfc..08ff55099c9c 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -196,7 +196,7 @@
<string name="choose_profile" msgid="343803890897657450">"Elegir perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Trabajo"</string>
- <string name="development_settings_title" msgid="140296922921597393">"Opciones para programadores"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"Opciones para desarrolladores"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activar opciones para programador"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Establecer opciones para desarrollar aplicaciones"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"Las opciones de programador no están disponibles para este usuario."</string>
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> para completar la carga"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batería limitada temporalmente"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápido"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ccdc1c443fbd..6f6a1a1c9b17 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> hasta cargarse completamente"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta cargarse completamente)"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g>: batería limitada temporalmente"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 852d6df7d31e..9d6326e45706 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Täislaadimiseni on jäänud <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – akutase on ajutiselt piiratud"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tundmatu"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Laadimine"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Kiirlaadimine"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6b6b9b63df65..01afa1706e3e 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g>: bateria mugatuta egongo da aldi batez"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ezezaguna"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Kargatzen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Bizkor kargatzen"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index af1e55be67c5..dd7ab9672e96 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> مانده تا شارژ کامل"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - باتری موقتاً محدود شده است"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ناشناس"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"در حال شارژ شدن"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"درحال شارژ شدن سریع"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 8e819efe3557..b86b02d8c25f 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä täyteen lataukseen"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Akun käyttöä rajoitettu tilapäisesti"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tuntematon"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Ladataan"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Nopea lataus"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 4754d15b5a52..0bca1dba1aa4 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la charge complète"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Pile limitée temporairement"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Charge en cours…"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Recharge rapide"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index a3863f596067..ebde43ba52a2 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à ce que la batterie soit chargée"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batterie limitée temporairement"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Batterie en charge"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charge rapide"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 81e79e4a27a9..b040817b2801 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> para completar a carga"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> (batería limitada temporalmente)"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Descoñecido"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rapidamente"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 9bf09704a4f5..c1bd7cac30a6 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"નિષ્ક્રિય. ટોગલ કરવા માટે ટૅપ કરો."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"સક્રિય. ટોગલ કરવા માટે ટૅપ કરો."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"ઍપ સ્ટૅન્ડબાયની સ્થિતિ:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"મીડિયાનું ફૉર્મેટ બદલવાની પ્રક્રિયાના સેટિંગ"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ફૉર્મેટ બદલવાની પ્રક્રિયા બંધ કરો"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ઍપ માટે ફૉર્મેટ બદલવાની પ્રક્રિયા ચાલુ કરો"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"ચાલુ સેવાઓ"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"હાલમાં ચાલતી સેવાઓ જુઓ અને નિયંત્રિત કરો"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView અમલીકરણ"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - બૅટરીનો વપરાશ હંગામી રૂપે મર્યાદિત છે"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"અજાણ્યું"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ઝડપથી ચાર્જ થાય છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 151b861cbd3b..d9153a1ab542 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"चार्ज पूरा होने में <xliff:g id="TIME">%1$s</xliff:g> बचा है"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - कुछ समय के लिए, बैटरी का सीमित इस्तेमाल होगा"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हो रही है"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"तेज़ चार्ज हो रही है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index d37879f6e153..b51e096ca6b7 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Napunit će se za <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – napunit će se za <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Baterija je privremeno ograničena"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 4ac5308474c5..33770fc1bdd8 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> van hátra a feltöltésből"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a feltöltésig"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Akkumulátor ideiglenesen korlátozva"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ismeretlen"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Töltés"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Gyorstöltés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index b0734fdee27e..06d70f854f27 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> մինչև լիցքավորումը"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լիցքավորումը"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Մարտկոցը ժամանակավորապես սահմանափակված է"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Անհայտ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Լիցքավորում"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Արագ լիցքավորում"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 9db21c796bbf..4123d9e3b755 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Sisa <xliff:g id="TIME">%1$s</xliff:g> hingga terisi penuh"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Daya baterai terbatas untuk sementara"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Mengisi daya"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengisi daya cepat"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d9ee03adefa4..3b9bef872177 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> að fullri hleðslu"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> að fullri hleðslu"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Rafhlaða takmörkuð tímabundið"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Óþekkt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Í hleðslu"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hröð hleðsla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 57378e78af65..1ab6b24456f3 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -66,7 +66,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Connessione…"</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connesso"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"Accoppiamento…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono escluso)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (contenuti multimediali esclusi)"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index fd53f14bd48f..15868d5fc997 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"אפליקציה לא פעילה. הקש כדי להחליף מצב."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"אפליקציה פעילה. הקש כדי להחליף מצב."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"אפליקציה במצב המתנה:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"הגדרות של המרת קידוד למדיה"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"השבתה של המרת קידוד"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"הפעלה של המרת קידוד לאפליקציות"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"שירותים פועלים"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"הצגת השירותים הפועלים כעת ושליטה בהם"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"‏יישום WebView"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"נשארו <xliff:g id="TIME">%1$s</xliff:g> עד הטעינה"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד הטעינה"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - הסוללה מוגבלת באופן זמני"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"לא ידוע"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"בטעינה"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"הסוללה נטענת מהר"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index c0aa74bafc56..89ee98eeeb42 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"充電完了まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電完了まで <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - 電池の使用が一時的に制限されています"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"急速充電中"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 09f3ff5c957a..2bc1c4d20728 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Зарядталғанға дейін <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батарея жұмысы уақытша шектелген"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Белгісіз"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядталуда"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 42e6a53a0078..7306cf8c5d3f 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើប​សាកថ្មពេញ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - បានដាក់កម្រិតថ្ម​ជាបណ្ដោះអាសន្ន"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"មិន​ស្គាល់"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"កំពុងបញ្ចូល​ថ្ម"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 658b987dd833..0c1502ca620d 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಇದೆ"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯ ಬೇಕು"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಬ್ಯಾಟರಿ ತಾತ್ಕಾಲಿಕವಾಗಿ ಸೀಮಿತವಾಗಿದೆ"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ಅಪರಿಚಿತ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ವೇಗದ ಚಾರ್ಜಿಂಗ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 2b0843dcef39..13223440d098 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"충전 완료까지 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - 일시적으로 배터리 사용 제한"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"알 수 없음"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"충전 중"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"고속 충전 중"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 499fd88f5a4f..9697aa70e44f 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> кийин толук кубатталып бүтөт"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталып бүтөт"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батареяны колдонуу убактлуу чектелген"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Белгисиз"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Кубатталууда"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index a5be6017ca62..720122262dcf 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -399,9 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"ບໍ່ໄດ້ນຳໃຊ້. ແຕະບໍ່ສັບປ່ຽນ."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"ນຳໃຊ້ຢູ່. ແຕະເພື່ອສັບປ່ຽນ."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"ສະຖານະສະແຕນບາຍແອັບ:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <string name="transcode_settings_title" msgid="2581975870429850549">"ການຕັ້ງຄ່າການ​ປ່ຽນ​ຮູບ​ແບບ​ລະ​ຫັດມີເດຍ"</string>
- <string name="transcode_enable_all" msgid="9102460144086871903">"ປິດການນຳໃຊ້ການ​ປ່ຽນ​ຮູບ​ແບບ​ລະ​ຫັດ"</string>
- <string name="transcode_skip_apps" msgid="8249721984597390142">"ເປີດການນຳໃຊ້ການ​ປ່ຽນ​ຮູບ​ແບບ​ລະ​ຫັດສຳລັບແອັບ"</string>
+ <string name="transcode_settings_title" msgid="2581975870429850549">"ການຕັ້ງຄ່າການປ່ຽນຮູບແບບລະຫັດມີເດຍ"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ປິດການນຳໃຊ້ການປ່ຽນຮູບແບບລະຫັດ"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ເປີດການນຳໃຊ້ການປ່ຽນຮູບແບບລະຫັດສຳລັບແອັບ"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"ບໍລິການທີ່ເຮັດວຽກຢູ່"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"ເບິ່ງ ແລະຈັດການບໍລິການທີ່ກຳລັງເຮັດວຽກຢູ່ໃນປັດຈຸບັນ"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"ການຈັດຕັ້ງປະຕິບັດ WebView"</string>
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຈຳກັດແບັດເຕີຣີຊົ່ວຄາວ"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ບໍ່ຮູ້ຈັກ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ກຳລັງສາກໄຟດ່ວນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 181fb10dd845..e62eeb2dbd97 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Iki visiškos įkrovos liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – iki visiškos įkrovos liko <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – akumuliatorius laikinai apribotas"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nežinomas"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Kraunasi..."</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Greitai įkraunama"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 717e2b0c89d8..2f305612a5fc 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Vēl <xliff:g id="TIME">%1$s</xliff:g> līdz pilnai uzlādei"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g>, akumulatora uzlāde pagaidām ierobežota"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nezināms"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Uzlāde"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Notiek ātrā uzlāde"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 2ccb150b8ca3..1936fe2d32a4 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Уште <xliff:g id="TIME">%1$s</xliff:g> до целосно полнење"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> до целосно полнење"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батеријата е привремено ограничена"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Се полни"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо полнење"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 768ad5e70698..de4a49a2ed06 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"നിഷ്‌ക്രിയം. മാറ്റുന്നതിനു ടാപ്പുചെയ്യുക."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"സജീവം. മാറ്റുന്നതിന് ടാപ്പുചെയ്യുക."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"ആപ്പ് സ്‌റ്റാൻഡ്‌ബൈ നില:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"മീഡിയ ട്രാൻസ്കോഡ് ചെയ്യൽ ക്രമീകരണം"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ട്രാൻസ്കോഡ് ചെയ്യൽ പ്രവർത്തനരഹിതമാക്കുക"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ആപ്പുകൾക്കായി ട്രാൻസ്കോഡ് ചെയ്യുന്നത് പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"നിലവിൽ പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ കാണുക, നിയന്ത്രിക്കുക"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView നടപ്പാക്കൽ"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"പൂർണ്ണമായി ചാർജാവാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായി ചാർജാവാൻ <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ബാറ്ററി താൽക്കാലം പരിമിതപ്പെടുത്തി"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"അജ്ഞാതം"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ചാർജ് ചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"അതിവേഗ ചാർജിംഗ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 61ebca5992b8..dee8add685f9 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Цэнэглэх хүртэл үлдсэн <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - цэнэглэх хүртэл <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батарейг түр хугацаанд хязгаарласан"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Тодорхойгүй"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хурдан цэнэглэж байна"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index ef319c3a4fc1..60ad68e42c09 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"निष्क्रिय. टॉगल करण्यासाठी टॅप करा."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"सक्रिय. टॉगल करण्यासाठी टॅप करा."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"अ‍ॅप स्टँडबाय स्थिती: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"मीडिया ट्रान्सकोडिंगची सेटिंग्ज"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ट्रान्सकोडिंग बंद करा"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ॲप्ससाठी ट्रान्सकोडिंग सुरू करा"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"सुरू सेवा"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"सध्या सुरू असलेल्या सेवा पहा आणि नियंत्रित करा"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"वेबदृश्य अंमलबजावणी"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> पर्यंत पूर्ण चार्ज होईल"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पर्यंत पूर्ण चार्ज होईल"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - बॅटरी तात्पुरती मर्यादित आहे"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"वेगाने चार्ज होत आहे"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 83c038453265..e4d591207937 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> lagi sehingga dicas penuh"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Bateri terhad untuk sementara"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Mengecas"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index f398487856bf..09a8bf87700b 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ဘက်ထရီ ယာယီကန့်သတ်ထားသည်"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"မသိ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"အားသွင်းနေပါသည်"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"အမြန် အားသွင်းနေသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 0ef5809e2a6d..d1af28940f1b 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> til batteriet er fulladet"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til batteriet er fulladet"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Batteriet er midlertidig begrenset"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ukjent"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Lader"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Lader raskt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index b956e2104c82..0c6114b9e220 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"निष्क्रिय। टगल गर्न ट्याप गर्नुहोस्।"</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"सक्रिय। टगल गर्न ट्याप गर्नुहोस्।"</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"एपको स्ट्यान्डबाई अवस्था:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"मिडिया ट्रान्सकोडिङ सेटिङ"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ट्रान्सकोडिङ अफ गर्नुहोस्"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"एपहरूमा ट्रान्सकोडिङ अन गर्नुहोस्"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"चलिरहेका सेवाहरू"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"हाल चालु भइरहेका सेवाहरू हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView कार्यान्वयन"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"पूर्ण चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"पूर्ण चार्ज हुन <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> लाग्छ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - केही समयका लागि ब्याट्री प्रयोग सीमित गरिएको छ"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 3223857a0949..a409756e5b5f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Nog <xliff:g id="TIME">%1$s</xliff:g> tot opgeladen"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot opgeladen"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batterij tijdelijk beperkt"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Opladen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Snel opladen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 11bb550caa49..0a0eeff6de60 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"ନିଷ୍କ୍ରିୟ। ଟୋଗଲ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ।"</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"ସକ୍ରିୟ। ବଦଳାଇବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ"</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"ଆପ୍ ଷ୍ଟାଣ୍ଡବାଏ ଅବସ୍ଥା:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"ମିଡିଆ ଟ୍ରାନ୍ସକୋଡିଂ ସେଟିଂସ୍"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ଟ୍ରାନ୍ସକୋଡିଂ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ଆପଗୁଡ଼ିକ ପାଇଁ ଟ୍ରାନ୍ସକୋଡିଂ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକ"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"ଏବେ ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ ଓ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"ୱେବ୍‌ଭ୍ୟୁ ପ୍ରୟୋଗ"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"ଚାର୍ଜ ହେବା ପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ଚାର୍ଜ ହେବା ପର୍ଯ୍ୟନ୍ତ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ବ୍ୟାଟେରୀ ଅସ୍ଥାୟୀ ଭାବେ ସୀମିତ ଅଛି"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ଅଜ୍ଞାତ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ଚାର୍ଜ ହେଉଛି"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ଶୀଘ୍ର ଚାର୍ଜ ହେଉଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 8d66f3ca4adc..c9c37d922537 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"ਅਕਿਰਿਆਸ਼ੀਲ। ਟੌਗਲ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"ਕਿਰਿਆਸ਼ੀਲ। ਟੌਗਲ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"ਐਪ ਸਟੈਂਡਬਾਈ ਸਥਿਤੀ:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"ਮੀਡੀਆ ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਬੰਦ ਕਰੋ"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ਐਪਾਂ ਲਈ ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"ਇਸ ਵੇਲੇ ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ ਦੇਖੋ ਅਤੇ ਇਹਨਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ਅਮਲ"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਤੱਕ ਚਾਰਜ ਹੋ ਜਾਵੇਗੀ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਕੁਝ ਸਮੇਂ ਲਈ ਸੀਮਤ"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ਅਗਿਆਤ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ਤੇਜ਼ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index ed96c46848d9..e894c2cbc34c 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Do naładowania <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – do naładowania <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – bateria tymczasowo ograniczona"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nieznane"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Ładowanie"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Szybkie ładowanie"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 46d6d0a89f5e..57a0454f3465 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Au mai rămas <xliff:g id="TIME">%1$s</xliff:g> până la încărcare"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> până la încărcare"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – baterie limitată temporar"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Necunoscut"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Se încarcă"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Se încarcă rapid"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 2a79ad3005ff..09b8de04388b 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> • Уровень заряда временно ограничен"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Идет зарядка"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Быстрая зарядка"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 78f355865ced..d36140f66b54 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"ආරෝපණය වන තෙක් <xliff:g id="TIME">%1$s</xliff:g> ඇත"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය වන තෙක් <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - බැටරිය තාවකාලිකව සීමිතයි"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"නොදනී"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ශීඝ්‍ර ආරෝපණය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 152c7a885457..096e95e7050b 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Zostávajúci čas do úplného nabitia: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Batéria je dočasne obmedzená"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Neznáme"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíja sa"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rýchle nabíjanie"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a2f093e89ad8..345fa36d3bd6 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Še <xliff:g id="TIME">%1$s</xliff:g> do polne napolnjenosti"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do polne napolnjenosti"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – baterija je začasno omejena"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Neznano"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Polnjenje"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hitro polnjenje"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index b4589173f234..3953a6a4f6e0 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura deri në karikim"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të karikohet"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Bateria e kufizuar përkohësisht"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Po ngarkon me shpejtësi"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 970c70f48c68..70b287933c93 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Напуниће се за <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – напуниће се за <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – батерија је тренутно ограничена"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Пуни се"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 42d907734e30..f466e882c2fc 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> kvar till full laddning"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till full laddning"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – batteriet är tillfälligt begränsat"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Okänd"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Laddar"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laddas snabbt"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index f1a41994d2c8..e1060fec2a66 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Imebakisha <xliff:g id="TIME">%1$s</xliff:g> ijae chaji"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ijae chaji"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Betri imedhibitiwa kwa muda"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Haijulikani"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Inachaji"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 2d696c5f79eb..ba98d79ff7e4 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g>-பேட்டரி தற்காலிகக் கட்டுப்பாட்டிலுள்ளது"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"அறியப்படாத"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"சார்ஜ் ஆகிறது"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"வேகமாக சார்ஜாகிறது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 8e0f0b603523..0b93979dbd07 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"ఛార్జ్ అవ్వడానికి <xliff:g id="TIME">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జ్ అవ్వడానికి <xliff:g id="TIME">%2$s</xliff:g> పడుతుంది"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> -బ్యాటరీ తాత్కాలికంగా పరిమితం చేయబడింది"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"తెలియదు"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"వేగవంతమైన ఛార్జింగ్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 81895b923a44..a31e14611bf6 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"เหลือ <xliff:g id="TIME">%1$s</xliff:g> จนกว่าจะชาร์จเต็ม"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จ"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - การชาร์จแบตเตอรี่จำกัดชั่วคราว"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จอย่างเร็ว"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 5d1630f28675..bbb77790e68a 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ang natitira bago matapos mag-charge"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang matapos mag-charge"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pansamantalang limitado ang baterya"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Hindi Kilala"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Nagcha-charge"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mabilis na charge"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 34c96a815616..fba7f41bbbf5 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Şarj olmaya <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - şarj olmaya <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pil geçici olarak sınırlı"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Bilinmiyor"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Şarj oluyor"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hızlı şarj oluyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index de2456cce092..b633752d28a9 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> до повного заряду"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – дані акумулятора тимчасово недоступні"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Невідомо"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Заряджається"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 7842ba9bcdbf..b4d8ad2576bd 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -399,12 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"غیر فعال۔ ٹوگل کرنے کیلئے تھپتھپائیں۔"</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"فعال۔ ٹوگل کرنے کیلئے تھپتھپائیں۔"</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"ایپ اسٹینڈ بائی کی حالت:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <!-- no translation found for transcode_settings_title (2581975870429850549) -->
- <skip />
- <!-- no translation found for transcode_enable_all (9102460144086871903) -->
- <skip />
- <!-- no translation found for transcode_skip_apps (8249721984597390142) -->
- <skip />
+ <string name="transcode_settings_title" msgid="2581975870429850549">"میڈیا ٹرانسکوڈنگ کی ترتیبات"</string>
+ <string name="transcode_enable_all" msgid="9102460144086871903">"ٹرانسکوڈنگ غیر فعال کریں"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"ایپس کے لئے ٹرانسکوڈنگ فعال کریں"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"چل رہی سروسز"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"فی الحال چل رہی سروسز دیکھیں اور انہیں کنٹرول کریں"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"‏WebView کا نفاذ"</string>
@@ -452,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> چارج ہونے تک"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - بیٹری عارضی طور پر محدود ہے"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"نامعلوم"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"تیزی سے چارج ہو رہا ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 9457d9001a88..5bb422ecf96a 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> ichida toʻladi"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida toʻladi"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quvvat darajasi vaqtincha cheklangan"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 235987c423d5..0acf9418b718 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Còn <xliff:g id="TIME">%1$s</xliff:g> nữa là sạc đầy"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> nữa là sạc đầy"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> – Thời lượng pin bị hạn chế tạm thời"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Không xác định"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Đang sạc"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Đang sạc nhanh"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 46188e9859e6..ca2ad87fb864 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"还剩 <xliff:g id="TIME">%1$s</xliff:g>充满电"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>后充满电"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - 暂时限用电池"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"正在充电"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充电"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 6f5c0253e94f..16ca19d313c1 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -399,9 +399,9 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"未啟用。輕按即可切換。"</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"已啟用。輕按即可切換。"</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"備用應用程式狀態:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <string name="transcode_settings_title" msgid="2581975870429850549">"媒體轉碼功能設定"</string>
+ <string name="transcode_settings_title" msgid="2581975870429850549">"媒體轉碼設定"</string>
<string name="transcode_enable_all" msgid="9102460144086871903">"停用轉碼功能"</string>
- <string name="transcode_skip_apps" msgid="8249721984597390142">"替應用程式啟用轉碼功能"</string>
+ <string name="transcode_skip_apps" msgid="8249721984597390142">"為應用程式啟用轉碼功能"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"執行中的服務"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"查看並控制目前正在執行中的服務"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 設置"</string>
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"還需 <xliff:g id="TIME">%1$s</xliff:g>才能充滿電"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能充滿電"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - 暫時限制電池充電"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充電"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index f966df68e0c3..810119b97777 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g>後充飽電"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽電"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - 暫時限制電池用量"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 8ad37d330bc4..23beeb1aee82 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -449,8 +449,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> esele ize ishaje"</string>
<string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ize igcwale"</string>
- <!-- no translation found for power_charging_limited (5902301801611726210) -->
- <skip />
+ <string name="power_charging_limited" msgid="5902301801611726210">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ibhethri ikhawulelwe okwesikhashana"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Akwaziwa"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Iyashaja"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ishaja ngokushesha"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 59d8acb82196..8fd1910041c8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -49,6 +49,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class BluetoothEventManager {
private static final String TAG = "BluetoothEventManager";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mDeviceManager;
@@ -366,6 +367,9 @@ public class BluetoothEventManager {
* BluetoothDevice.UNBOND_REASON_*
*/
private void showUnbondMessage(Context context, String name, int reason) {
+ if (DEBUG) {
+ Log.d(TAG, "showUnbondMessage() name : " + name + ", reason : " + reason);
+ }
int errorMsg;
switch (reason) {
@@ -382,6 +386,7 @@ public class BluetoothEventManager {
case BluetoothDevice.UNBOND_REASON_AUTH_TIMEOUT:
case BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS:
case BluetoothDevice.UNBOND_REASON_REMOTE_AUTH_CANCELED:
+ case BluetoothDevice.UNBOND_REASON_REMOVED:
errorMsg = R.string.bluetooth_pairing_error_message;
break;
default:
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
index ba1dc64ce1e6..6a4d650ebf31 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
@@ -35,6 +35,8 @@ import android.content.IntentFilter;
import android.os.UserHandle;
import android.telephony.TelephonyManager;
+import com.android.settingslib.R;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,6 +51,8 @@ import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class BluetoothEventManagerTest {
+ private static final String DEVICE_NAME = "test_device_name";
+
@Mock
private LocalBluetoothAdapter mLocalAdapter;
@Mock
@@ -71,6 +75,8 @@ public class BluetoothEventManagerTest {
private BluetoothDevice mDevice2;
@Mock
private LocalBluetoothProfileManager mLocalProfileManager;
+ @Mock
+ private BluetoothUtils.ErrorListener mErrorListener;
private Context mContext;
private Intent mIntent;
@@ -92,6 +98,7 @@ public class BluetoothEventManagerTest {
mCachedDevice1 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1);
mCachedDevice2 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2);
+ BluetoothUtils.setErrorListener(mErrorListener);
}
@Test
@@ -344,4 +351,80 @@ public class BluetoothEventManagerTest {
assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
}
+
+ @Test
+ public void showUnbondMessage_reasonRemoved_showCorrectedErrorCode() {
+ mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
+ mIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
+ mIntent.putExtra(BluetoothDevice.EXTRA_REASON, BluetoothDevice.UNBOND_REASON_REMOVED);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice1);
+ when(mCachedDevice1.getName()).thenReturn(DEVICE_NAME);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mErrorListener).onShowError(any(Context.class), eq(DEVICE_NAME),
+ eq(R.string.bluetooth_pairing_error_message));
+ }
+
+ @Test
+ public void showUnbondMessage_reasonAuthTimeout_showCorrectedErrorCode() {
+ mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
+ mIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
+ mIntent.putExtra(BluetoothDevice.EXTRA_REASON, BluetoothDevice.UNBOND_REASON_AUTH_TIMEOUT);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice1);
+ when(mCachedDevice1.getName()).thenReturn(DEVICE_NAME);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mErrorListener).onShowError(any(Context.class), eq(DEVICE_NAME),
+ eq(R.string.bluetooth_pairing_error_message));
+ }
+
+ @Test
+ public void showUnbondMessage_reasonRemoteDeviceDown_showCorrectedErrorCode() {
+ mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
+ mIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
+ mIntent.putExtra(BluetoothDevice.EXTRA_REASON,
+ BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice1);
+ when(mCachedDevice1.getName()).thenReturn(DEVICE_NAME);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mErrorListener).onShowError(any(Context.class), eq(DEVICE_NAME),
+ eq(R.string.bluetooth_pairing_device_down_error_message));
+ }
+
+ @Test
+ public void showUnbondMessage_reasonAuthRejected_showCorrectedErrorCode() {
+ mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
+ mIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
+ mIntent.putExtra(BluetoothDevice.EXTRA_REASON, BluetoothDevice.UNBOND_REASON_AUTH_REJECTED);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice1);
+ when(mCachedDevice1.getName()).thenReturn(DEVICE_NAME);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mErrorListener).onShowError(any(Context.class), eq(DEVICE_NAME),
+ eq(R.string.bluetooth_pairing_rejected_error_message));
+ }
+
+ @Test
+ public void showUnbondMessage_reasonAuthFailed_showCorrectedErrorCode() {
+ mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
+ mIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
+ mIntent.putExtra(BluetoothDevice.EXTRA_REASON, BluetoothDevice.UNBOND_REASON_AUTH_FAILED);
+ when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedDevice1);
+ when(mCachedDevice1.getName()).thenReturn(DEVICE_NAME);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mErrorListener).onShowError(any(Context.class), eq(DEVICE_NAME),
+ eq(R.string.bluetooth_pairing_pin_error_message));
+ }
}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index b75c2c4cea6c..c82bda6620bd 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -95,7 +95,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
- android:textSize="170dp"
+ android:textSize="180dp"
android:letterSpacing="0.02"
android:lineSpacingMultiplier=".8"
android:includeFontPadding="false"
diff --git a/packages/SystemUI/res-product/values/strings.xml b/packages/SystemUI/res-product/values/strings.xml
index f1c539e8eb4e..c1e81bacbec5 100644
--- a/packages/SystemUI/res-product/values/strings.xml
+++ b/packages/SystemUI/res-product/values/strings.xml
@@ -23,7 +23,7 @@
<!-- Indication when device is not charging due to bad placement on the dock. [CHAR LIMIT=60] -->
<string name="dock_alignment_not_charging" product="default">Realign phone to charge wirelessly</string>
- <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
+ <!-- Message of the overlay warning the user that the TV is about to go to standby unless a TV remote button is pressed. [CHAR LIMIT=NONE] -->
<string name="inattentive_sleep_warning_message" product="tv">The Android TV device will soon turn off; press a button to keep it on.</string>
<!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
<string name="inattentive_sleep_warning_message" product="default">The device will soon turn off; press to keep it on.</string>
diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
index 7d45de3fa50d..30ffc32ce1f8 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
@@ -1,67 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/global_actions_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
- <com.android.systemui.globalactions.GlobalActionsFlatLayout
- android:id="@id/global_actions_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:theme="@style/qs_theme"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:layout_marginStart="@dimen/global_actions_side_margin"
- >
- <LinearLayout
- android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/global_actions_grid_vertical_padding"
- android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
- android:orientation="horizontal"
- android:gravity="left | center_vertical"
- android:translationZ="@dimen/global_actions_translate"
- >
- <RelativeLayout
- android:id="@+id/global_actions_overflow_button"
- android:contentDescription="@string/accessibility_menu"
- android:layout_width="48dp"
- android:layout_height="48dp"
- >
- <ImageView
- android:src="@drawable/ic_more_vert"
- android:layout_centerInParent="true"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:tint="@color/control_more_vert"
- />
- </RelativeLayout>
- </LinearLayout>
- </com.android.systemui.globalactions.GlobalActionsFlatLayout>
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/global_actions_lock_message_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone">
- <TextView
- android:id="@+id/global_actions_lock_message"
- style="@style/TextAppearance.Control.Title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/global_actions_side_margin"
- android:drawablePadding="12dp"
- android:gravity="center"
- android:text="@string/global_action_lock_message"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.35"/>
- </androidx.constraintlayout.widget.ConstraintLayout>
+ <include layout="@layout/global_actions_view" />
+
+ <include layout="@layout/global_actions_lock_view" />
<com.android.systemui.globalactions.MinHeightScrollView
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/global_actions_lock_view.xml b/packages/SystemUI/res/layout/global_actions_lock_view.xml
new file mode 100644
index 000000000000..eccc63688065
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_lock_view.xml
@@ -0,0 +1,35 @@
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/global_actions_lock_message_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone">
+ <TextView
+ android:id="@+id/global_actions_lock_message"
+ style="@style/TextAppearance.Control.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="@dimen/global_actions_side_margin"
+ android:drawablePadding="12dp"
+ android:gravity="center"
+ android:text="@string/global_action_lock_message"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.35"/>
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_actions_view.xml b/packages/SystemUI/res/layout/global_actions_view.xml
new file mode 100644
index 000000000000..454707bc44e2
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_view.xml
@@ -0,0 +1,52 @@
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<com.android.systemui.globalactions.GlobalActionsFlatLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@id/global_actions_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:theme="@style/qs_theme"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_marginStart="@dimen/global_actions_side_margin"
+ >
+ <LinearLayout
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/global_actions_grid_vertical_padding"
+ android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
+ android:orientation="horizontal"
+ android:gravity="left | center_vertical"
+ android:translationZ="@dimen/global_actions_translate"
+ >
+ <RelativeLayout
+ android:id="@+id/global_actions_overflow_button"
+ android:contentDescription="@string/accessibility_menu"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ >
+ <ImageView
+ android:src="@drawable/ic_more_vert"
+ android:layout_centerInParent="true"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:tint="@color/control_more_vert"
+ />
+ </RelativeLayout>
+ </LinearLayout>
+</com.android.systemui.globalactions.GlobalActionsFlatLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 880dd378e390..01b55b70d5ad 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -357,9 +357,6 @@
the notification is not swiped enough to dismiss it. -->
<bool name="config_showNotificationGear">true</bool>
- <!-- Whether or not a background should be drawn behind a notification. -->
- <bool name="config_drawNotificationBackground">true</bool>
-
<!-- Whether or the notifications can be shown and dismissed with a drag. -->
<bool name="config_enableNotificationShadeDrag">true</bool>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index a32cd1420fdc..3cbab8e66fdb 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -244,7 +244,7 @@ public class KeyguardSliceView extends LinearLayout {
iconDrawable.setBounds(0, 0, Math.max(width, 1), iconSize);
}
}
- button.setCompoundDrawables(iconDrawable, null, null, null);
+ button.setCompoundDrawablesRelative(iconDrawable, null, null, null);
button.setOnClickListener(mOnClickListener);
button.setClickable(pendingIntent != null);
}
@@ -536,9 +536,9 @@ public class KeyguardSliceView extends LinearLayout {
}
@Override
- public void setCompoundDrawables(Drawable left, Drawable top, Drawable right,
+ public void setCompoundDrawablesRelative(Drawable start, Drawable top, Drawable end,
Drawable bottom) {
- super.setCompoundDrawables(left, top, right, bottom);
+ super.setCompoundDrawablesRelative(start, top, end, bottom);
updateDrawableColors();
updatePadding();
}
@@ -558,9 +558,9 @@ public class KeyguardSliceView extends LinearLayout {
public void setLockScreenMode(int mode) {
mLockScreenMode = mode;
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
- setGravity(Gravity.START);
+ setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
} else {
- setGravity(Gravity.CENTER);
+ setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
}
updatePadding();
}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 6151ac7a242b..3852b24fe4b3 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -327,8 +327,8 @@ public class SwipeHelper implements Gefingerpoken {
if (Math.abs(delta) > pagingTouchSlop
&& Math.abs(delta) > Math.abs(deltaPerpendicular)) {
if (mCallback.canChildBeDragged(mTouchedView)) {
- mCallback.onBeginDrag(mTouchedView);
mIsSwiping = true;
+ mCallback.onBeginDrag(mTouchedView);
mInitialTouchPos = getPos(ev);
mTranslation = getTranslation(mTouchedView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index f6b8b4c92049..70a57cc8bd2a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -185,8 +185,12 @@ public class BrightLineFalsingManager implements FalsingManager {
return true;
}
- // TODO(b/172655679): we always reject single-taps when doing a robust check for now.
- return robustCheck;
+ // TODO(b/172655679): More heuristics to come. For now, allow touches through if face-authed
+ if (robustCheck) {
+ return !mDataProvider.isJustUnlockedWithFace();
+ }
+
+ return false;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 885048df13f1..ac3b6d26fab6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -82,9 +82,6 @@ public class AmbientState {
private ExpandableNotificationRow mTrackedHeadsUpRow;
private float mAppearFraction;
- /** Tracks the state from AlertingNotificationManager#hasNotifications() */
- private boolean mHasAlertEntries;
-
public AmbientState(
Context context,
@NonNull SectionProvider sectionProvider) {
@@ -368,21 +365,10 @@ public class AmbientState {
mPanelTracking = panelTracking;
}
- public boolean hasPulsingNotifications() {
- return mPulsing && mHasAlertEntries;
- }
-
public void setPulsing(boolean hasPulsing) {
mPulsing = hasPulsing;
}
- /**
- * @return if we're pulsing in general
- */
- public boolean isPulsing() {
- return mPulsing;
- }
-
public boolean isPulsing(NotificationEntry entry) {
return mPulsing && entry.isAlerting();
}
@@ -541,8 +527,4 @@ public class AmbientState {
public float getAppearFraction() {
return mAppearFraction;
}
-
- public void setHasAlertEntries(boolean hasAlertEntries) {
- mHasAlertEntries = hasAlertEntries;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index 1131a65abe93..ba03a50b0ba5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -31,175 +31,22 @@ import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.row.ExpandableView;
/**
- * Represents the bounds of a section of the notification shade and handles animation when the
- * bounds change.
+ * Represents the priority of a notification section and tracks first and last visible children.
*/
public class NotificationSection {
private @PriorityBucket int mBucket;
- private View mOwningView;
- private Rect mBounds = new Rect();
- private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
- private Rect mStartAnimationRect = new Rect();
- private Rect mEndAnimationRect = new Rect();
- private ObjectAnimator mTopAnimator = null;
- private ObjectAnimator mBottomAnimator = null;
private ExpandableView mFirstVisibleChild;
private ExpandableView mLastVisibleChild;
- NotificationSection(View owningView, @PriorityBucket int bucket) {
- mOwningView = owningView;
+ NotificationSection(@PriorityBucket int bucket) {
mBucket = bucket;
}
- public void cancelAnimators() {
- if (mBottomAnimator != null) {
- mBottomAnimator.cancel();
- }
- if (mTopAnimator != null) {
- mTopAnimator.cancel();
- }
- }
-
- public Rect getCurrentBounds() {
- return mCurrentBounds;
- }
-
- public Rect getBounds() {
- return mBounds;
- }
-
- public boolean didBoundsChange() {
- return !mCurrentBounds.equals(mBounds);
- }
-
- public boolean areBoundsAnimating() {
- return mBottomAnimator != null || mTopAnimator != null;
- }
-
@PriorityBucket
public int getBucket() {
return mBucket;
}
- public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) {
- // Left and right bounds are always applied immediately.
- mCurrentBounds.left = mBounds.left;
- mCurrentBounds.right = mBounds.right;
- startBottomAnimation(animateBottom);
- startTopAnimation(animateTop);
- }
-
-
- @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
- private void startTopAnimation(boolean animate) {
- int previousEndValue = mEndAnimationRect.top;
- int newEndValue = mBounds.top;
- ObjectAnimator previousAnimator = mTopAnimator;
- if (previousAnimator != null && previousEndValue == newEndValue) {
- return;
- }
- if (!animate) {
- // just a local update was performed
- if (previousAnimator != null) {
- // we need to increase all animation keyframes of the previous animator by the
- // relative change to the end value
- int previousStartValue = mStartAnimationRect.top;
- PropertyValuesHolder[] values = previousAnimator.getValues();
- values[0].setIntValues(previousStartValue, newEndValue);
- mStartAnimationRect.top = previousStartValue;
- mEndAnimationRect.top = newEndValue;
- previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
- return;
- } else {
- // no new animation needed, let's just apply the value
- setBackgroundTop(newEndValue);
- return;
- }
- }
- if (previousAnimator != null) {
- previousAnimator.cancel();
- }
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
- mCurrentBounds.top, newEndValue);
- Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
- animator.setInterpolator(interpolator);
- animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartAnimationRect.top = -1;
- mEndAnimationRect.top = -1;
- mTopAnimator = null;
- }
- });
- animator.start();
- mStartAnimationRect.top = mCurrentBounds.top;
- mEndAnimationRect.top = newEndValue;
- mTopAnimator = animator;
- }
-
- @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
- private void startBottomAnimation(boolean animate) {
- int previousStartValue = mStartAnimationRect.bottom;
- int previousEndValue = mEndAnimationRect.bottom;
- int newEndValue = mBounds.bottom;
- ObjectAnimator previousAnimator = mBottomAnimator;
- if (previousAnimator != null && previousEndValue == newEndValue) {
- return;
- }
- if (!animate) {
- // just a local update was performed
- if (previousAnimator != null) {
- // we need to increase all animation keyframes of the previous animator by the
- // relative change to the end value
- PropertyValuesHolder[] values = previousAnimator.getValues();
- values[0].setIntValues(previousStartValue, newEndValue);
- mStartAnimationRect.bottom = previousStartValue;
- mEndAnimationRect.bottom = newEndValue;
- previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
- return;
- } else {
- // no new animation needed, let's just apply the value
- setBackgroundBottom(newEndValue);
- return;
- }
- }
- if (previousAnimator != null) {
- previousAnimator.cancel();
- }
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
- mCurrentBounds.bottom, newEndValue);
- Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
- animator.setInterpolator(interpolator);
- animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartAnimationRect.bottom = -1;
- mEndAnimationRect.bottom = -1;
- mBottomAnimator = null;
- }
- });
- animator.start();
- mStartAnimationRect.bottom = mCurrentBounds.bottom;
- mEndAnimationRect.bottom = newEndValue;
- mBottomAnimator = animator;
- }
-
- @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
- private void setBackgroundTop(int top) {
- mCurrentBounds.top = top;
- mOwningView.invalidate();
- }
-
- @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
- private void setBackgroundBottom(int bottom) {
- mCurrentBounds.bottom = bottom;
- mOwningView.invalidate();
- }
-
public ExpandableView getFirstVisibleChild() {
return mFirstVisibleChild;
}
@@ -219,93 +66,4 @@ public class NotificationSection {
mLastVisibleChild = child;
return changed;
}
-
- public void resetCurrentBounds() {
- mCurrentBounds.set(mBounds);
- }
-
- /**
- * Returns true if {@code top} is equal to the top of this section (if not currently animating)
- * or where the top of this section will be when animation completes.
- */
- public boolean isTargetTop(int top) {
- return (mTopAnimator == null && mCurrentBounds.top == top)
- || (mTopAnimator != null && mEndAnimationRect.top == top);
- }
-
- /**
- * Returns true if {@code bottom} is equal to the bottom of this section (if not currently
- * animating) or where the bottom of this section will be when animation completes.
- */
- public boolean isTargetBottom(int bottom) {
- return (mBottomAnimator == null && mCurrentBounds.bottom == bottom)
- || (mBottomAnimator != null && mEndAnimationRect.bottom == bottom);
- }
-
- /**
- * Update the bounds of this section based on it's views
- *
- * @param minTopPosition the minimum position that the top needs to have
- * @param minBottomPosition the minimum position that the bottom needs to have
- * @return the position of the new bottom
- */
- public int updateBounds(int minTopPosition, int minBottomPosition,
- boolean shiftBackgroundWithFirst) {
- int top = minTopPosition;
- int bottom = minTopPosition;
- ExpandableView firstView = getFirstVisibleChild();
- if (firstView != null) {
- // Round Y up to avoid seeing the background during animation
- int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
- // TODO: look into the already animating part
- int newTop;
- if (isTargetTop(finalTranslationY)) {
- // we're ending up at the same location as we are now, let's just skip the
- // animation
- newTop = finalTranslationY;
- } else {
- newTop = (int) Math.ceil(firstView.getTranslationY());
- }
- top = Math.max(newTop, top);
- if (firstView.showingPulsing()) {
- // If we're pulsing, the notification can actually go below!
- bottom = Math.max(bottom, finalTranslationY
- + ExpandableViewState.getFinalActualHeight(firstView));
- if (shiftBackgroundWithFirst) {
- mBounds.left += Math.max(firstView.getTranslation(), 0);
- mBounds.right += Math.min(firstView.getTranslation(), 0);
- }
- }
- }
- top = Math.max(minTopPosition, top);
- ExpandableView lastView = getLastVisibleChild();
- if (lastView != null) {
- float finalTranslationY = ViewState.getFinalTranslationY(lastView);
- int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
- // Round Y down to avoid seeing the background during animation
- int finalBottom = (int) Math.floor(
- finalTranslationY + finalHeight - lastView.getClipBottomAmount());
- int newBottom;
- if (isTargetBottom(finalBottom)) {
- // we're ending up at the same location as we are now, lets just skip the animation
- newBottom = finalBottom;
- } else {
- newBottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
- - lastView.getClipBottomAmount());
- // The background can never be lower than the end of the last view
- minBottomPosition = (int) Math.min(
- lastView.getTranslationY() + lastView.getActualHeight(),
- minBottomPosition);
- }
- bottom = Math.max(bottom, Math.max(newBottom, minBottomPosition));
- }
- bottom = Math.max(top, bottom);
- mBounds.top = top;
- mBounds.bottom = bottom;
- return bottom;
- }
-
- public boolean needsBackground() {
- return mFirstVisibleChild != null && mBucket != BUCKET_MEDIA_CONTROLS;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 4f7e14ba4a4c..36c5419b7399 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -126,7 +126,7 @@ class NotificationSectionsManager @Inject internal constructor(
fun createSectionsForBuckets(): Array<NotificationSection> =
sectionsFeatureManager.getNotificationBuckets()
- .map { NotificationSection(parent, it) }
+ .map { NotificationSection(it) }
.toTypedArray()
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 742e517e71e7..ba5f95e9c4d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -38,12 +38,9 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PointF;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserHandle;
@@ -73,7 +70,6 @@ import android.widget.OverScroller;
import android.widget.ScrollView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.graphics.ColorUtils;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.KeyguardSliceView;
@@ -158,8 +154,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private ExpandHelper mExpandHelper;
private NotificationSwipeHelper mSwipeHelper;
private int mCurrentStackHeight = Integer.MAX_VALUE;
- private final Paint mBackgroundPaint = new Paint();
- private final boolean mShouldDrawNotificationBackground;
private boolean mHighPriorityBeforeSpeedBump;
private boolean mDismissRtl;
@@ -258,7 +252,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
protected FooterView mFooterView;
protected EmptyShadeView mEmptyShadeView;
private boolean mDismissAllInProgress;
- private boolean mFadeNotificationsOnDismiss;
private FooterDismissListener mFooterDismissListener;
private boolean mFlingAfterUpEvent;
@@ -328,10 +321,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
};
private NotificationSection[] mSections;
- private boolean mAnimateNextBackgroundTop;
- private boolean mAnimateNextBackgroundBottom;
- private boolean mAnimateNextSectionBoundsChange;
- private int mBgColor;
private float mDimAmount;
private ValueAnimator mDimAnimator;
private ArrayList<ExpandableView> mTmpSortedChildren = new ArrayList<>();
@@ -342,25 +331,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
};
private ValueAnimator.AnimatorUpdateListener mDimUpdateListener
- = new ValueAnimator.AnimatorUpdateListener() {
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- setDimAmount((Float) animation.getAnimatedValue());
- }
- };
+ = animation -> setDimAmount((Float) animation.getAnimatedValue());
protected ViewGroup mQsContainer;
private boolean mContinuousShadowUpdate;
- private boolean mContinuousBackgroundUpdate;
private ViewTreeObserver.OnPreDrawListener mShadowUpdater
= () -> {
updateViewShadows();
return true;
};
- private ViewTreeObserver.OnPreDrawListener mBackgroundUpdater = () -> {
- updateBackground();
- return true;
- };
private Comparator<ExpandableView> mViewPositionComparator = (view, otherView) -> {
float endY = view.getTranslationY() + view.getActualHeight();
float otherEndY = otherView.getTranslationY() + otherView.getActualHeight();
@@ -379,7 +357,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
if (mAmbientState.isHiddenAtAll()) {
float xProgress = mHideXInterpolator.getInterpolation(
(1 - mLinearHideAmount) * mBackgroundXFactor);
- outline.setRoundRect(mBackgroundAnimationRect,
+ outline.setRoundRect(mOutlineAnimationRect,
MathUtils.lerp(mCornerRadius / 2.0f, mCornerRadius,
xProgress));
outline.setAlpha(1.0f - mAmbientState.getHideAmount());
@@ -388,7 +366,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
}
};
- private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
private boolean mPulsing;
private boolean mScrollable;
private View mForcedScroll;
@@ -422,7 +399,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private boolean mInHeadsUpPinnedMode;
private boolean mHeadsUpAnimatingAway;
private int mStatusBarState;
- private int mCachedBackgroundColor;
private boolean mHeadsUpGoingAwayAnimationsAllowed = true;
private Runnable mReflingAndAnimateScroll = () -> {
if (ANCHOR_SCROLLING) {
@@ -432,7 +408,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
};
private int mCornerRadius;
private int mSidePaddings;
- private final Rect mBackgroundAnimationRect = new Rect();
+ private final Rect mOutlineAnimationRect = new Rect();
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
private int mHeadsUpInset;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
@@ -452,7 +428,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private final NotificationSectionsManager mSectionsManager;
private ForegroundServiceDungeonView mFgsSectionView;
- private boolean mAnimateBottomOnLayout;
private float mLastSentAppear;
private float mLastSentExpandedHeight;
private boolean mWillExpand;
@@ -463,7 +438,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private boolean mKeyguardMediaControllorVisible;
private NotificationEntry mTopHeadsUpEntry;
- private long mNumHeadsUp;
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
@@ -530,7 +504,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSections = mSectionsManager.createSectionsForBuckets();
mAmbientState = new AmbientState(context, mSectionsManager);
- mBgColor = context.getColor(R.color.notification_shade_background_color);
int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
mExpandHelper = new ExpandHelper(getContext(), mExpandHelperCallback,
@@ -539,13 +512,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mExpandHelper.setScrollAdapter(mScrollAdapter);
mStackScrollAlgorithm = createStackScrollAlgorithm(context);
- mShouldDrawNotificationBackground =
- res.getBoolean(R.bool.config_drawNotificationBackground);
setOutlineProvider(mOutlineProvider);
- boolean willDraw = mShouldDrawNotificationBackground || DEBUG;
- setWillNotDraw(!willDraw);
- mBackgroundPaint.setAntiAlias(true);
+ setWillNotDraw(!DEBUG);
if (DEBUG) {
mDebugPaint = new Paint();
mDebugPaint.setColor(0xffff0000);
@@ -590,7 +559,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
* @return the height at which we will wake up when pulsing
*/
public float getWakeUpHeight() {
- ExpandableView firstChild = getFirstChildWithBackground();
+ ExpandableView firstChild = getFirstExpandableView();
if (firstChild != null) {
if (mKeyguardBypassEnabledProvider.getBypassEnabled()) {
return firstChild.getHeadsUpHeightWithoutHeader();
@@ -641,22 +610,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
void updateBgColor() {
- mBgColor = mContext.getColor(R.color.notification_shade_background_color);
- updateBackgroundDimming();
mShelf.onUiModeChanged();
}
@ShadeViewRefactor(RefactorComponent.DECORATOR)
protected void onDraw(Canvas canvas) {
- if (mShouldDrawNotificationBackground
- && (mSections[0].getCurrentBounds().top
- < mSections[mSections.length - 1].getCurrentBounds().bottom
- || mAmbientState.isDozing())) {
- drawBackground(canvas);
- } else if (mInHeadsUpPinnedMode || mHeadsUpAnimatingAway) {
- drawHeadsUpBackground(canvas);
- }
-
if (DEBUG) {
int y = mTopPadding;
canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
@@ -691,160 +649,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
}
- @ShadeViewRefactor(RefactorComponent.DECORATOR)
- private void drawBackground(Canvas canvas) {
- int lockScreenLeft = mSidePaddings;
- int lockScreenRight = getWidth() - mSidePaddings;
- int lockScreenTop = mSections[0].getCurrentBounds().top;
- int lockScreenBottom = mSections[mSections.length - 1].getCurrentBounds().bottom;
- int hiddenLeft = getWidth() / 2;
- int hiddenTop = mTopPadding;
-
- float yProgress = 1 - mInterpolatedHideAmount;
- float xProgress = mHideXInterpolator.getInterpolation(
- (1 - mLinearHideAmount) * mBackgroundXFactor);
-
- int left = (int) MathUtils.lerp(hiddenLeft, lockScreenLeft, xProgress);
- int right = (int) MathUtils.lerp(hiddenLeft, lockScreenRight, xProgress);
- int top = (int) MathUtils.lerp(hiddenTop, lockScreenTop, yProgress);
- int bottom = (int) MathUtils.lerp(hiddenTop, lockScreenBottom, yProgress);
- mBackgroundAnimationRect.set(
- left,
- top,
- right,
- bottom);
-
- int backgroundTopAnimationOffset = top - lockScreenTop;
- // TODO(kprevas): this may not be necessary any more since we don't display the shelf in AOD
- boolean anySectionHasVisibleChild = false;
- for (NotificationSection section : mSections) {
- if (section.needsBackground()) {
- anySectionHasVisibleChild = true;
- break;
- }
- }
- boolean shouldDrawBackground;
- if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) {
- shouldDrawBackground = isPulseExpanding();
- } else {
- shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild;
- }
- if (shouldDrawBackground) {
- drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset);
- }
-
- updateClipping();
- }
-
- /**
- * Draws round rects for each background section.
- *
- * We want to draw a round rect for each background section as defined by {@link #mSections}.
- * However, if two sections are directly adjacent with no gap between them (e.g. on the
- * lockscreen where the shelf can appear directly below the high priority section, or while
- * scrolling the shade so that the top of the shelf is right at the bottom of the high priority
- * section), we don't want to round the adjacent corners.
- *
- * Since {@link Canvas} doesn't provide a way to draw a half-rounded rect, this means that we
- * need to coalesce the backgrounds for adjacent sections and draw them as a single round rect.
- * This method tracks the top of each rect we need to draw, then iterates through the visible
- * sections. If a section is not adjacent to the previous section, we draw the previous rect
- * behind the sections we've accumulated up to that point, then start a new rect at the top of
- * the current section. When we're done iterating we will always have one rect left to draw.
- */
- private void drawBackgroundRects(Canvas canvas, int left, int right, int top,
- int animationYOffset) {
- int backgroundRectTop = top;
- int lastSectionBottom =
- mSections[0].getCurrentBounds().bottom + animationYOffset;
- int currentLeft = left;
- int currentRight = right;
- boolean first = true;
- for (NotificationSection section : mSections) {
- if (!section.needsBackground()) {
- continue;
- }
- int sectionTop = section.getCurrentBounds().top + animationYOffset;
- int ownLeft = Math.min(Math.max(left, section.getCurrentBounds().left), right);
- int ownRight = Math.max(Math.min(right, section.getCurrentBounds().right), ownLeft);
- // If sections are directly adjacent to each other, we don't want to draw them
- // as separate roundrects, as the rounded corners right next to each other look
- // bad.
- if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX
- || ((currentLeft != ownLeft || currentRight != ownRight) && !first)) {
- canvas.drawRoundRect(currentLeft,
- backgroundRectTop,
- currentRight,
- lastSectionBottom,
- mCornerRadius, mCornerRadius, mBackgroundPaint);
- backgroundRectTop = sectionTop;
- }
- currentLeft = ownLeft;
- currentRight = ownRight;
- lastSectionBottom =
- section.getCurrentBounds().bottom + animationYOffset;
- first = false;
- }
- canvas.drawRoundRect(currentLeft,
- backgroundRectTop,
- currentRight,
- lastSectionBottom,
- mCornerRadius, mCornerRadius, mBackgroundPaint);
- }
-
- private void drawHeadsUpBackground(Canvas canvas) {
- int left = mSidePaddings;
- int right = getWidth() - mSidePaddings;
-
- float top = getHeight();
- float bottom = 0;
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child.getVisibility() != View.GONE
- && child instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if ((row.isPinned() || row.isHeadsUpAnimatingAway()) && row.getTranslation() < 0
- && row.getProvider().shouldShowGutsOnSnapOpen()) {
- top = Math.min(top, row.getTranslationY());
- bottom = Math.max(bottom, row.getTranslationY() + row.getActualHeight());
- }
- }
- }
-
- if (top < bottom) {
- canvas.drawRoundRect(
- left, top, right, bottom,
- mCornerRadius, mCornerRadius, mBackgroundPaint);
- }
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- void updateBackgroundDimming() {
- // No need to update the background color if it's not being drawn.
- if (!mShouldDrawNotificationBackground) {
- return;
- }
- final boolean newFlowHideShelf = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.SHOW_NEW_NOTIF_DISMISS, 1 /* on by default */) == 1;
- if (newFlowHideShelf) {
- mBackgroundPaint.setColor(Color.TRANSPARENT);
- invalidate();
- return;
- }
- // Interpolate between semi-transparent notification panel background color
- // and white AOD separator.
- float colorInterpolation = MathUtils.smoothStep(0.4f /* start */, 1f /* end */,
- mLinearHideAmount);
- int color = ColorUtils.blendARGB(mBgColor, Color.WHITE, colorInterpolation);
-
- if (mCachedBackgroundColor != color) {
- mCachedBackgroundColor = color;
- mBackgroundPaint.setColor(color);
- invalidate();
- }
- }
-
private void reinitView() {
initView(getContext(), mKeyguardBypassEnabledProvider, mSwipeHelper);
}
@@ -979,7 +783,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateContentHeight();
clampScrollPosition();
requestChildrenUpdate();
- updateFirstAndLastBackgroundViews();
+ updateFirstAndLastExpandableView();
updateAlgorithmLayoutMinHeight();
updateOwnTranslationZ();
}
@@ -1050,9 +854,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private void onPreDrawDuringAnimation() {
mShelf.updateAppearance();
updateClippingToTopRoundedCorner();
- if (!mNeedsAnimation && !mChildrenUpdateRequested) {
- updateBackground();
- }
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -2369,131 +2170,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
}
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void updateBackground() {
- // No need to update the background color if it's not being drawn.
- if (!mShouldDrawNotificationBackground) {
- return;
- }
-
- updateBackgroundBounds();
- if (didSectionBoundsChange()) {
- boolean animate = mAnimateNextSectionBoundsChange || mAnimateNextBackgroundTop
- || mAnimateNextBackgroundBottom || areSectionBoundsAnimating();
- if (!isExpanded()) {
- abortBackgroundAnimators();
- animate = false;
- }
- if (animate) {
- startBackgroundAnimation();
- } else {
- for (NotificationSection section : mSections) {
- section.resetCurrentBounds();
- }
- invalidate();
- }
- } else {
- abortBackgroundAnimators();
- }
- mAnimateNextBackgroundTop = false;
- mAnimateNextBackgroundBottom = false;
- mAnimateNextSectionBoundsChange = false;
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void abortBackgroundAnimators() {
- for (NotificationSection section : mSections) {
- section.cancelAnimators();
- }
- }
-
- private boolean didSectionBoundsChange() {
- for (NotificationSection section : mSections) {
- if (section.didBoundsChange()) {
- return true;
- }
- }
- return false;
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private boolean areSectionBoundsAnimating() {
- for (NotificationSection section : mSections) {
- if (section.areBoundsAnimating()) {
- return true;
- }
- }
- return false;
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void startBackgroundAnimation() {
- // TODO(kprevas): do we still need separate fields for top/bottom?
- // or can each section manage its own animation state?
- NotificationSection firstVisibleSection = getFirstVisibleSection();
- NotificationSection lastVisibleSection = getLastVisibleSection();
- for (NotificationSection section : mSections) {
- section.startBackgroundAnimation(
- section == firstVisibleSection
- ? mAnimateNextBackgroundTop
- : mAnimateNextSectionBoundsChange,
- section == lastVisibleSection
- ? mAnimateNextBackgroundBottom
- : mAnimateNextSectionBoundsChange);
- }
- }
-
- /**
- * Update the background bounds to the new desired bounds
- */
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void updateBackgroundBounds() {
- int left = mSidePaddings;
- int right = getWidth() - mSidePaddings;
- for (NotificationSection section : mSections) {
- section.getBounds().left = left;
- section.getBounds().right = right;
- }
-
- if (!mIsExpanded) {
- for (NotificationSection section : mSections) {
- section.getBounds().top = 0;
- section.getBounds().bottom = 0;
- }
- return;
- }
- int minTopPosition;
- NotificationSection lastSection = getLastVisibleSection();
- boolean onKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
- if (!onKeyguard) {
- minTopPosition = (int) (mTopPadding + mStackTranslation);
- } else if (lastSection == null) {
- minTopPosition = mTopPadding;
- } else {
- // The first sections could be empty while there could still be elements in later
- // sections. The position of these first few sections is determined by the position of
- // the first visible section.
- NotificationSection firstVisibleSection = getFirstVisibleSection();
- firstVisibleSection.updateBounds(0 /* minTopPosition*/, 0 /* minBottomPosition */,
- false /* shiftPulsingWithFirst */);
- minTopPosition = firstVisibleSection.getBounds().top;
- }
- boolean shiftPulsingWithFirst = mNumHeadsUp <= 1
- && (mAmbientState.isDozing()
- || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard));
- for (NotificationSection section : mSections) {
- int minBottomPosition = minTopPosition;
- if (section == lastSection) {
- // We need to make sure the section goes all the way to the shelf
- minBottomPosition = (int) (ViewState.getFinalTranslationY(mShelf)
- + mShelf.getIntrinsicHeight());
- }
- minTopPosition = section.updateBounds(minTopPosition, minBottomPosition,
- shiftPulsingWithFirst);
- shiftPulsingWithFirst = false;
- }
- }
-
private NotificationSection getFirstVisibleSection() {
for (NotificationSection section : mSections) {
if (section.getFirstVisibleChild() != null) {
@@ -2514,7 +2190,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- private ExpandableView getLastChildWithBackground() {
+ private ExpandableView getLastExpandableView() {
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
ExpandableView child = (ExpandableView) getChildAt(i);
@@ -2527,7 +2203,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- private ExpandableView getFirstChildWithBackground() {
+ private ExpandableView getFirstExpandableView() {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
ExpandableView child = (ExpandableView) getChildAt(i);
@@ -2540,7 +2216,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
//TODO: We shouldn't have to generate this list every time
- private List<ExpandableView> getChildrenWithBackground() {
+ private List<ExpandableView> getExpandableViewList() {
ArrayList<ExpandableView> children = new ArrayList<>();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -3078,32 +2754,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void updateFirstAndLastBackgroundViews() {
- NotificationSection firstSection = getFirstVisibleSection();
- NotificationSection lastSection = getLastVisibleSection();
- ExpandableView previousFirstChild =
- firstSection == null ? null : firstSection.getFirstVisibleChild();
- ExpandableView previousLastChild =
- lastSection == null ? null : lastSection.getLastVisibleChild();
-
- ExpandableView firstChild = getFirstChildWithBackground();
- ExpandableView lastChild = getLastChildWithBackground();
- boolean sectionViewsChanged = mSectionsManager.updateFirstAndLastViewsForAllSections(
- mSections, getChildrenWithBackground());
-
- if (mAnimationsEnabled && mIsExpanded) {
- mAnimateNextBackgroundTop = firstChild != previousFirstChild;
- mAnimateNextBackgroundBottom = lastChild != previousLastChild || mAnimateBottomOnLayout;
- mAnimateNextSectionBoundsChange = sectionViewsChanged;
- } else {
- mAnimateNextBackgroundTop = false;
- mAnimateNextBackgroundBottom = false;
- mAnimateNextSectionBoundsChange = false;
- }
+ private void updateFirstAndLastExpandableView() {
+ ExpandableView lastChild = getLastExpandableView();
+ mSectionsManager.updateFirstAndLastViewsForAllSections(
+ mSections, getExpandableViewList());
mAmbientState.setLastVisibleBackgroundChild(lastChild);
// TODO: Refactor SectionManager and put the RoundnessManager there.
mController.getNoticationRoundessManager().updateRoundedChildren(mSections);
- mAnimateBottomOnLayout = false;
invalidate();
}
@@ -3265,7 +2922,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
setAnimationRunning(true);
mStateAnimator.startAnimationForEvents(mAnimationEvents, mGoToFullShadeDelay);
mAnimationEvents.clear();
- updateBackground();
updateViewShadows();
updateClippingToTopRoundedCorner();
} else {
@@ -4350,7 +4006,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void setDimAmount(float dimAmount) {
mDimAmount = dimAmount;
- updateBackgroundDimming();
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4419,7 +4074,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
runAnimationFinishedRunnables();
setAnimationRunning(false);
- updateBackground();
updateViewShadows();
updateClippingToTopRoundedCorner();
}
@@ -4554,7 +4208,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
invalidateOutline();
}
updateAlgorithmHeightAndPadding();
- updateBackgroundDimming();
requestChildrenUpdate();
updateOwnTranslationZ();
}
@@ -5435,7 +5088,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
*/
public void setDozeAmount(float dozeAmount) {
mAmbientState.setDozeAmount(dozeAmount);
- updateContinuousBackgroundDrawing();
requestChildrenUpdate();
}
@@ -5473,7 +5125,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
void setAnimateBottomOnLayout(boolean animateBottomOnLayout) {
- mAnimateBottomOnLayout = animateBottomOnLayout;
}
public void setOnPulseHeightChangedListener(Runnable listener) {
@@ -5506,25 +5157,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
void onSwipeBegin() {
requestDisallowInterceptTouchEvent(true);
- updateFirstAndLastBackgroundViews();
updateContinuousShadowDrawing();
- updateContinuousBackgroundDrawing();
requestChildrenUpdate();
}
- void onSwipeEnd() {
- updateFirstAndLastBackgroundViews();
- }
-
void setTopHeadsUpEntry(NotificationEntry topEntry) {
mTopHeadsUpEntry = topEntry;
}
- void setNumHeadsUp(long numHeadsUp) {
- mNumHeadsUp = numHeadsUp;
- mAmbientState.setHasAlertEntries(numHeadsUp > 0);
- }
-
public boolean getIsExpanded() {
return mIsExpanded;
}
@@ -5639,27 +5279,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSectionsManager.updateSectionBoundaries(reason);
}
- boolean isSilkDismissEnabled() {
- return Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.SHOW_NEW_NOTIF_DISMISS, 1 /* enabled by default */) == 1;
- }
-
- void updateContinuousBackgroundDrawing() {
- if (isSilkDismissEnabled()) {
- return;
- }
- boolean continuousBackground = !mAmbientState.isFullyAwake()
- && mSwipeHelper.isSwiping();
- if (continuousBackground != mContinuousBackgroundUpdate) {
- mContinuousBackgroundUpdate = continuousBackground;
- if (continuousBackground) {
- getViewTreeObserver().addOnPreDrawListener(mBackgroundUpdater);
- } else {
- getViewTreeObserver().removeOnPreDrawListener(mBackgroundUpdater);
- }
- }
- }
-
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
void updateContinuousShadowDrawing() {
boolean continuousShadowUpdate = mAnimationRunning
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 9d4665a5eeca..abbbbb8352f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -394,7 +394,6 @@ public class NotificationStackScrollLayoutController {
if (mView.getDismissAllInProgress()) {
return;
}
- mView.onSwipeEnd();
if (view instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
if (row.isHeadsUp()) {
@@ -454,7 +453,6 @@ public class NotificationStackScrollLayoutController {
@Override
public void onChildSnappedBack(View animView, float targetLeft) {
- mView.onSwipeEnd();
if (animView instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
if (row.isPinned() && !canChildBeDismissed(row)
@@ -518,9 +516,7 @@ public class NotificationStackScrollLayoutController {
@Override
public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
- long numEntries = mHeadsUpManager.getAllEntries().count();
NotificationEntry topEntry = mHeadsUpManager.getTopEntry();
- mView.setNumHeadsUp(numEntries);
mView.setTopHeadsUpEntry(topEntry);
mNotificationRoundnessManager.updateView(entry.getRow(), false /* animate */);
}
@@ -665,8 +661,6 @@ public class NotificationStackScrollLayoutController {
mHeadsUpManager.setAnimationStateHandler(mView::setHeadsUpGoingAwayAnimationsAllowed);
mDynamicPrivacyController.addListener(mDynamicPrivacyControllerListener);
- mScrimController.setScrimBehindChangeRunnable(mView::updateBackgroundDimming);
-
mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
mFadeNotificationsOnDismiss = // TODO: this should probably be injected directly
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2fe37d48379b..e8ee18c6f4d4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2771,6 +2771,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
networkCapabilities = new NetworkCapabilities(networkCapabilities);
networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
}
+ processCapabilitiesFromAgent(nai, networkCapabilities);
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
break;
}
@@ -2809,6 +2810,31 @@ public class ConnectivityService extends IConnectivityManager.Stub
mKeepaliveTracker.handleEventSocketKeepalive(nai, msg);
break;
}
+ case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
+ if (!nai.supportsUnderlyingNetworks()) {
+ Log.wtf(TAG, "Non-virtual networks cannot have underlying networks");
+ break;
+ }
+ final ArrayList<Network> underlying;
+ try {
+ underlying = ((Bundle) msg.obj).getParcelableArrayList(
+ NetworkAgent.UNDERLYING_NETWORKS_KEY);
+ } catch (NullPointerException | ClassCastException e) {
+ break;
+ }
+ final Network[] oldUnderlying = nai.declaredUnderlyingNetworks;
+ nai.declaredUnderlyingNetworks = (underlying != null)
+ ? underlying.toArray(new Network[0]) : null;
+
+ if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) {
+ if (DBG) {
+ log(nai.toShortString() + " changed underlying networks to "
+ + Arrays.toString(nai.declaredUnderlyingNetworks));
+ }
+ updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
+ notifyIfacesChangedForNetworkStats();
+ }
+ }
}
}
@@ -3394,7 +3420,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
mLegacyTypeTracker.remove(nai, wasDefault);
if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
- updateAllVpnsCapabilities();
+ propagateUnderlyingNetworkCapabilities();
}
rematchAllNetworksAndRequests();
mLingerMonitor.noteDisconnect(nai);
@@ -4704,10 +4730,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (mLockdownEnabled) {
return new VpnInfo[0];
}
-
List<VpnInfo> infoList = new ArrayList<>();
- for (int i = 0; i < mVpns.size(); i++) {
- VpnInfo info = createVpnInfo(mVpns.valueAt(i));
+ for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+ VpnInfo info = createVpnInfo(nai);
if (info != null) {
infoList.add(info);
}
@@ -4720,13 +4745,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @return VPN information for accounting, or null if we can't retrieve all required
* information, e.g underlying ifaces.
*/
- @Nullable
- private VpnInfo createVpnInfo(Vpn vpn) {
- VpnInfo info = vpn.getVpnInfo();
- if (info == null) {
- return null;
- }
- Network[] underlyingNetworks = vpn.getUnderlyingNetworks();
+ private VpnInfo createVpnInfo(NetworkAgentInfo nai) {
+ if (!nai.isVPN()) return null;
+
+ Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
// see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
// the underlyingNetworks list.
if (underlyingNetworks == null) {
@@ -4735,23 +4757,33 @@ public class ConnectivityService extends IConnectivityManager.Stub
underlyingNetworks = new Network[] { defaultNai.network };
}
}
- if (underlyingNetworks != null && underlyingNetworks.length > 0) {
- List<String> interfaces = new ArrayList<>();
- for (Network network : underlyingNetworks) {
- LinkProperties lp = getLinkProperties(network);
- if (lp != null) {
- for (String iface : lp.getAllInterfaceNames()) {
- if (!TextUtils.isEmpty(iface)) {
- interfaces.add(iface);
- }
- }
+
+ if (ArrayUtils.isEmpty(underlyingNetworks)) return null;
+
+ List<String> interfaces = new ArrayList<>();
+ for (Network network : underlyingNetworks) {
+ NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network);
+ if (underlyingNai == null) continue;
+ LinkProperties lp = underlyingNai.linkProperties;
+ for (String iface : lp.getAllInterfaceNames()) {
+ if (!TextUtils.isEmpty(iface)) {
+ interfaces.add(iface);
}
}
- if (!interfaces.isEmpty()) {
- info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]);
- }
}
- return info.underlyingIfaces == null ? null : info;
+
+ if (interfaces.isEmpty()) return null;
+
+ VpnInfo info = new VpnInfo();
+ info.ownerUid = nai.networkCapabilities.getOwnerUid();
+ info.vpnIface = nai.linkProperties.getInterfaceName();
+ // Must be non-null or NetworkStatsService will crash.
+ // Cannot happen in production code because Vpn only registers the NetworkAgent after the
+ // tun or ipsec interface is created.
+ if (info.vpnIface == null) return null;
+ info.underlyingIfaces = interfaces.toArray(new String[0]);
+
+ return info;
}
/**
@@ -4774,33 +4806,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
/**
- * Ask all VPN objects to recompute and update their capabilities.
+ * Ask all networks with underlying networks to recompute and update their capabilities.
*
- * When underlying networks change, VPNs may have to update capabilities to reflect things
- * like the metered bit, their transports, and so on. This asks the VPN objects to update
- * their capabilities, and as this will cause them to send messages to the ConnectivityService
- * handler thread through their agent, this is asynchronous. When the capabilities objects
- * are computed they will be up-to-date as they are computed synchronously from here and
- * this is running on the ConnectivityService thread.
+ * When underlying networks change, such networks may have to update capabilities to reflect
+ * things like the metered bit, their transports, and so on. The capabilities are calculated
+ * immediately. This method runs on the ConnectivityService thread.
*/
- private void updateAllVpnsCapabilities() {
- Network defaultNetwork = getNetwork(getDefaultNetwork());
- synchronized (mVpns) {
- for (int i = 0; i < mVpns.size(); i++) {
- final Vpn vpn = mVpns.valueAt(i);
- NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
- updateVpnCapabilities(vpn, nc);
- }
- }
- }
-
- private void updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc) {
+ private void propagateUnderlyingNetworkCapabilities() {
ensureRunningOnConnectivityServiceThread();
- NetworkAgentInfo vpnNai = getNetworkAgentInfoForNetId(vpn.getNetId());
- if (vpnNai == null || nc == null) {
- return;
+ for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+ if (nai.supportsUnderlyingNetworks()) {
+ updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
+ }
}
- updateCapabilities(vpnNai.getCurrentScore(), vpnNai, nc);
}
@Override
@@ -5113,7 +5131,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void onUserStart(int userId) {
+ private void onUserStarted(int userId) {
synchronized (mVpns) {
Vpn userVpn = mVpns.get(userId);
if (userVpn != null) {
@@ -5128,7 +5146,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void onUserStop(int userId) {
+ private void onUserStopped(int userId) {
synchronized (mVpns) {
Vpn userVpn = mVpns.get(userId);
if (userVpn == null) {
@@ -5142,28 +5160,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void onUserAdded(int userId) {
mPermissionMonitor.onUserAdded(userId);
- Network defaultNetwork = getNetwork(getDefaultNetwork());
synchronized (mVpns) {
final int vpnsSize = mVpns.size();
for (int i = 0; i < vpnsSize; i++) {
Vpn vpn = mVpns.valueAt(i);
vpn.onUserAdded(userId);
- NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
- updateVpnCapabilities(vpn, nc);
}
}
}
private void onUserRemoved(int userId) {
mPermissionMonitor.onUserRemoved(userId);
- Network defaultNetwork = getNetwork(getDefaultNetwork());
synchronized (mVpns) {
final int vpnsSize = mVpns.size();
for (int i = 0; i < vpnsSize; i++) {
Vpn vpn = mVpns.valueAt(i);
vpn.onUserRemoved(userId);
- NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
- updateVpnCapabilities(vpn, nc);
}
}
}
@@ -5245,9 +5257,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (userId == UserHandle.USER_NULL) return;
if (Intent.ACTION_USER_STARTED.equals(action)) {
- onUserStart(userId);
+ onUserStarted(userId);
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
- onUserStop(userId);
+ onUserStopped(userId);
} else if (Intent.ACTION_USER_ADDED.equals(action)) {
onUserAdded(userId);
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
@@ -5959,13 +5971,29 @@ public class ConnectivityService extends IConnectivityManager.Stub
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
+ } else {
+ enforceNetworkFactoryPermission();
+ }
+
+ final int uid = Binder.getCallingUid();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return registerNetworkAgentInternal(messenger, networkInfo, linkProperties,
+ networkCapabilities, currentScore, networkAgentConfig, providerId, uid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private Network registerNetworkAgentInternal(Messenger messenger, NetworkInfo networkInfo,
+ LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
+ int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) {
+ if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
// Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
// the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
// sees capabilities that may be malicious, which might prevent mistakes in the future.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(Binder.getCallingUid());
- } else {
- enforceNetworkFactoryPermission();
+ networkCapabilities.restrictCapabilitesForTestNetwork(uid);
}
LinkProperties lp = new LinkProperties(linkProperties);
@@ -5976,9 +6004,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
- this, mNetd, mDnsResolver, mNMS, providerId, Binder.getCallingUid());
+ this, mNetd, mDnsResolver, mNMS, providerId, uid);
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
+ processCapabilitiesFromAgent(nai, nc);
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
processLinkPropertiesFromAgent(nai, nai.linkProperties);
@@ -5986,13 +6015,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final String name = TextUtils.isEmpty(extraInfo)
? nai.networkCapabilities.getSsid() : extraInfo;
if (DBG) log("registerNetworkAgent " + nai);
- final long token = Binder.clearCallingIdentity();
- try {
- mDeps.getNetworkStack().makeNetworkMonitor(
- nai.network, name, new NetworkMonitorCallbacks(nai));
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ mDeps.getNetworkStack().makeNetworkMonitor(
+ nai.network, name, new NetworkMonitorCallbacks(nai));
// NetworkAgentInfo registration will finish when the NetworkMonitor is created.
// If the network disconnects or sends any other event before that, messages are deferred by
// NetworkAgent until nai.asyncChannel.connect(), which will be called when finalizing the
@@ -6019,6 +6043,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
updateUids(nai, null, nai.networkCapabilities);
}
+ /**
+ * Called when receiving LinkProperties directly from a NetworkAgent.
+ * Stores into |nai| any data coming from the agent that might also be written to the network's
+ * LinkProperties by ConnectivityService itself. This ensures that the data provided by the
+ * agent is not lost when updateLinkProperties is called.
+ */
private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
lp.ensureDirectlyConnectedRoutes();
nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
@@ -6315,6 +6345,30 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
/**
+ * Called when receiving NetworkCapabilities directly from a NetworkAgent.
+ * Stores into |nai| any data coming from the agent that might also be written to the network's
+ * NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the
+ * agent is not lost when updateCapabilities is called.
+ */
+ private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) {
+ nai.declaredMetered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
+ }
+
+ /** Propagates to |nc| the capabilities declared by the underlying networks of |nai|. */
+ private void mixInUnderlyingCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
+ Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
+ Network defaultNetwork = getNetwork(getDefaultNetwork());
+ if (underlyingNetworks == null && defaultNetwork != null) {
+ // null underlying networks means to track the default.
+ underlyingNetworks = new Network[] { defaultNetwork };
+ }
+
+ // TODO(b/124469351): Get capabilities directly from ConnectivityService instead.
+ final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+ Vpn.applyUnderlyingCapabilities(cm, underlyingNetworks, nc, nai.declaredMetered);
+ }
+
+ /**
* Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
* maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
* and foreground status).
@@ -6367,6 +6421,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
}
+ if (nai.supportsUnderlyingNetworks()) {
+ mixInUnderlyingCapabilities(nai, newNc);
+ }
+
return newNc;
}
@@ -6446,7 +6504,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (!newNc.hasTransport(TRANSPORT_VPN)) {
// Tell VPNs about updated capabilities, since they may need to
// bubble those changes through.
- updateAllVpnsCapabilities();
+ propagateUnderlyingNetworkCapabilities();
}
if (!newNc.equalsTransportTypes(prevNc)) {
@@ -6766,7 +6824,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
? newNetwork.linkProperties.getTcpBufferSizes() : null);
notifyIfacesChangedForNetworkStats();
// Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks.
- updateAllVpnsCapabilities();
+ propagateUnderlyingNetworkCapabilities();
}
private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
@@ -7228,7 +7286,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as
// the VPN would switch from its default, blank capabilities to those
// that reflect the capabilities of its underlying networks.
- updateAllVpnsCapabilities();
+ propagateUnderlyingNetworkCapabilities();
}
networkAgent.created = true;
}
@@ -7270,8 +7328,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// doing.
updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
- if (networkAgent.isVPN()) {
- updateAllVpnsCapabilities();
+ if (networkAgent.supportsUnderlyingNetworks()) {
+ propagateUnderlyingNetworkCapabilities();
}
// Consider network even though it is not yet validated.
@@ -7528,13 +7586,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
throwIfLockdownEnabled();
success = mVpns.get(user).setUnderlyingNetworks(networks);
}
- if (success) {
- mHandler.post(() -> {
- // Update VPN's capabilities based on updated underlying network set.
- updateAllVpnsCapabilities();
- notifyIfacesChangedForNetworkStats();
- });
- }
return success;
}
@@ -8210,13 +8261,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
return false;
}
- final Network[] underlyingNetworks;
- synchronized (mVpns) {
- final Vpn vpn = getVpnIfOwner(callbackUid);
- underlyingNetworks = (vpn == null) ? null : vpn.getUnderlyingNetworks();
- }
- if (underlyingNetworks != null) {
- if (Arrays.asList(underlyingNetworks).contains(nai.network)) return true;
+ for (NetworkAgentInfo virtual : mNetworkAgentInfos.values()) {
+ if (virtual.supportsUnderlyingNetworks()
+ && virtual.networkCapabilities.getOwnerUid() == callbackUid
+ && ArrayUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) {
+ return true;
+ }
}
// Administrator UIDs also contains the Owner UID
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index e67b9d8ccd91..8706cdf41df9 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -6,3 +6,6 @@ per-file VibratorManagerService.java, VibratorService.java, DisplayThread.java =
# Zram writeback
per-file ZramWriteback.java = minchan@google.com, rajekumar@google.com, srnvs@google.com
+
+# Userspace reboot
+per-file UserspaceRebootLogger.java = ioffe@google.com, tomcherry@google.com
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index e8e1a16d116b..a1cf8162f0e9 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.provider.DeviceConfig.Properties;
+
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import android.annotation.NonNull;
@@ -36,6 +38,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.ExceptionUtils;
import android.util.Log;
@@ -93,6 +96,12 @@ public class RescueParty {
static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2);
@VisibleForTesting
static final int DEVICE_CONFIG_RESET_MODE = Settings.RESET_MODE_TRUSTED_DEFAULTS;
+ // The DeviceConfig namespace containing all RescueParty switches.
+ @VisibleForTesting
+ static final String NAMESPACE_CONFIGURATION = "configuration";
+ @VisibleForTesting
+ static final String NAMESPACE_TO_PACKAGE_MAPPING_FLAG =
+ "namespace_to_package_mapping";
private static final String NAME = "rescue-party-observer";
@@ -103,8 +112,6 @@ public class RescueParty {
"persist.device_config.configuration.disable_rescue_party";
private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
"persist.device_config.configuration.disable_rescue_party_factory_reset";
- // The DeviceConfig namespace containing all RescueParty switches.
- private static final String NAMESPACE_CONFIGURATION = "configuration";
private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT
| ApplicationInfo.FLAG_SYSTEM;
@@ -170,6 +177,81 @@ public class RescueParty {
}));
}
+
+ /**
+ * Called when {@code RollbackManager} performs Mainline module rollbacks,
+ * to avoid rolled back modules consuming flag values only expected to work
+ * on modules of newer versions.
+ */
+ public static void resetDeviceConfigForPackages(List<String> packageNames) {
+ if (packageNames == null) {
+ return;
+ }
+ Set<String> namespacesToReset = new ArraySet<String>();
+ Iterator<String> it = packageNames.iterator();
+ RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstanceIfCreated();
+ // Get runtime package to namespace mapping if created.
+ if (rescuePartyObserver != null) {
+ while (it.hasNext()) {
+ String packageName = it.next();
+ Set<String> runtimeAffectedNamespaces =
+ rescuePartyObserver.getAffectedNamespaceSet(packageName);
+ if (runtimeAffectedNamespaces != null) {
+ namespacesToReset.addAll(runtimeAffectedNamespaces);
+ }
+ }
+ }
+ // Get preset package to namespace mapping if created.
+ Set<String> presetAffectedNamespaces = getPresetNamespacesForPackages(
+ packageNames);
+ if (presetAffectedNamespaces != null) {
+ namespacesToReset.addAll(presetAffectedNamespaces);
+ }
+
+ // Clear flags under the namespaces mapped to these packages.
+ // Using setProperties since DeviceConfig.resetToDefaults bans the current flag set.
+ Iterator<String> namespaceIt = namespacesToReset.iterator();
+ while (namespaceIt.hasNext()) {
+ String namespaceToReset = namespaceIt.next();
+ Properties properties = new Properties.Builder(namespaceToReset).build();
+ try {
+ DeviceConfig.setProperties(properties);
+ } catch (DeviceConfig.BadConfigException exception) {
+ logCriticalInfo(Log.WARN, "namespace " + namespaceToReset
+ + " is already banned, skip reset.");
+ }
+ }
+ }
+
+ private static Set<String> getPresetNamespacesForPackages(List<String> packageNames) {
+ Set<String> resultSet = new ArraySet<String>();
+ try {
+ String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION,
+ NAMESPACE_TO_PACKAGE_MAPPING_FLAG, "");
+ String[] mappingEntries = flagVal.split(",");
+ for (int i = 0; i < mappingEntries.length; i++) {
+ if (TextUtils.isEmpty(mappingEntries[i])) {
+ continue;
+ }
+ String[] splittedEntry = mappingEntries[i].split(":");
+ if (splittedEntry.length != 2) {
+ throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]);
+ }
+ String namespace = splittedEntry[0];
+ String packageName = splittedEntry[1];
+
+ if (packageNames.contains(packageName)) {
+ resultSet.add(namespace);
+ }
+ }
+ } catch (Exception e) {
+ resultSet.clear();
+ Slog.e(TAG, "Failed to read preset package to namespaces mapping.", e);
+ } finally {
+ return resultSet;
+ }
+ }
+
@VisibleForTesting
static long getElapsedRealtime() {
return SystemClock.elapsedRealtime();
@@ -469,6 +551,14 @@ public class RescueParty {
}
}
+ /** Gets singleton instance. It returns null if the instance is not created yet.*/
+ @Nullable
+ public static RescuePartyObserver getInstanceIfCreated() {
+ synchronized (RescuePartyObserver.class) {
+ return sRescuePartyObserver;
+ }
+ }
+
@VisibleForTesting
static void reset() {
synchronized (RescuePartyObserver.class) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 8033ce787b5f..04a52e049474 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3213,6 +3213,9 @@ class StorageManagerService extends IStorageManager.Stub
try {
mVold.unlockUserKey(userId, serialNumber, encodeBytes(token),
encodeBytes(secret));
+ } catch (ServiceSpecificException sse) {
+ Slog.d(TAG, "Expected if the user has not unlocked the device.", sse);
+ return;
} catch (Exception e) {
Slog.wtf(TAG, e);
return;
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index ebeec39d6ae6..95af84293377 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -29,6 +29,10 @@
{
"name": "CtsScopedStorageHostTest",
"file_patterns": ["StorageManagerService\\.java"]
+ },
+ {
+ "name": "CtsScopedStorageDeviceOnlyTest",
+ "file_patterns": ["StorageManagerService\\.java"]
}
]
}
diff --git a/services/core/java/com/android/server/UserspaceRebootLogger.java b/services/core/java/com/android/server/UserspaceRebootLogger.java
index 2403b637581f..89327b50883c 100644
--- a/services/core/java/com/android/server/UserspaceRebootLogger.java
+++ b/services/core/java/com/android/server/UserspaceRebootLogger.java
@@ -59,7 +59,7 @@ public final class UserspaceRebootLogger {
*/
public static void noteUserspaceRebootWasRequested() {
if (!PowerManager.isRebootingUserspaceSupportedImpl()) {
- Slog.wtf(TAG, "Userspace reboot is not supported.");
+ Slog.wtf(TAG, "noteUserspaceRebootWasRequested: Userspace reboot is not supported.");
return;
}
@@ -77,7 +77,7 @@ public final class UserspaceRebootLogger {
*/
public static void noteUserspaceRebootSuccess() {
if (!PowerManager.isRebootingUserspaceSupportedImpl()) {
- Slog.wtf(TAG, "Userspace reboot is not supported.");
+ Slog.wtf(TAG, "noteUserspaceRebootSuccess: Userspace reboot is not supported.");
return;
}
@@ -88,11 +88,11 @@ public final class UserspaceRebootLogger {
/**
* Returns {@code true} if {@code UserspaceRebootReported} atom should be logged.
*
- * <p>This call should only be made on devices supporting userspace reboot.
+ * <p>On devices that do not support userspace reboot this method will always return {@code
+ * false}.
*/
public static boolean shouldLogUserspaceRebootEvent() {
if (!PowerManager.isRebootingUserspaceSupportedImpl()) {
- Slog.wtf(TAG, "Userspace reboot is not supported.");
return false;
}
@@ -110,7 +110,7 @@ public final class UserspaceRebootLogger {
*/
public static void logEventAsync(boolean userUnlocked, Executor executor) {
if (!PowerManager.isRebootingUserspaceSupportedImpl()) {
- Slog.wtf(TAG, "Userspace reboot is not supported.");
+ Slog.wtf(TAG, "logEventAsync: Userspace reboot is not supported.");
return;
}
diff --git a/services/core/java/com/android/server/VibratorManagerService.java b/services/core/java/com/android/server/VibratorManagerService.java
index 356cd0cd937b..f1f2815be8fa 100644
--- a/services/core/java/com/android/server/VibratorManagerService.java
+++ b/services/core/java/com/android/server/VibratorManagerService.java
@@ -159,7 +159,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
pw.println(" Prints this help text.");
pw.println("");
pw.println(" list");
- pw.println(" Prints the id of device vibrators. This do not include any ");
+ pw.println(" Prints the id of device vibrators. This does not include any ");
pw.println(" connected input device.");
pw.println("");
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index e662553af731..db2b4e4edd2b 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -16,8 +16,6 @@
package com.android.server;
-import static android.os.VibrationEffect.Composition.PrimitiveEffect;
-
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
@@ -28,8 +26,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
-import android.content.res.Resources;
-import android.hardware.input.InputManager;
import android.hardware.vibrator.IVibrator;
import android.os.BatteryStats;
import android.os.Binder;
@@ -45,7 +41,6 @@ import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.Process;
-import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -60,38 +55,33 @@ import android.os.WorkSource;
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
-import android.view.InputDevice;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.vibrator.InputDeviceDelegate;
+import com.android.server.vibrator.Vibration;
import com.android.server.vibrator.VibrationScaler;
import com.android.server.vibrator.VibrationSettings;
-
-import libcore.util.NativeAllocationRegistry;
+import com.android.server.vibrator.VibratorController;
+import com.android.server.vibrator.VibratorController.OnVibrationCompleteListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
-public class VibratorService extends IVibratorService.Stub
- implements InputManager.InputDeviceListener {
+/** System implementation of {@link IVibratorService}. */
+public class VibratorService extends IVibratorService.Stub {
private static final String TAG = "VibratorService";
- private static final SimpleDateFormat DEBUG_DATE_FORMAT =
- new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
private static final boolean DEBUG = false;
private static final String EXTERNAL_VIBRATOR_SERVICE = "external_vibrator_service";
- private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = { 0, 30, 100, 30 };
-
// Default vibration attributes. Used when vibration is requested without attributes
private static final VibrationAttributes DEFAULT_ATTRIBUTES =
new VibrationAttributes.Builder().build();
@@ -99,22 +89,17 @@ public class VibratorService extends IVibratorService.Stub
// Used to generate globally unique vibration ids.
private final AtomicInteger mNextVibrationId = new AtomicInteger(1); // 0 = no callback
- private final LinkedList<VibrationInfo> mPreviousRingVibrations;
- private final LinkedList<VibrationInfo> mPreviousNotificationVibrations;
- private final LinkedList<VibrationInfo> mPreviousAlarmVibrations;
- private final LinkedList<VibrationInfo> mPreviousExternalVibrations;
- private final LinkedList<VibrationInfo> mPreviousVibrations;
+ private final LinkedList<Vibration.DebugInfo> mPreviousRingVibrations;
+ private final LinkedList<Vibration.DebugInfo> mPreviousNotificationVibrations;
+ private final LinkedList<Vibration.DebugInfo> mPreviousAlarmVibrations;
+ private final LinkedList<Vibration.DebugInfo> mPreviousExternalVibrations;
+ private final LinkedList<Vibration.DebugInfo> mPreviousVibrations;
private final int mPreviousVibrationsLimit;
- private final boolean mAllowPriorityVibrationsInLowPowerMode;
- private final List<Integer> mSupportedEffects;
- private final List<Integer> mSupportedPrimitives;
- private final long mCapabilities;
- private final int mDefaultVibrationAmplitude;
- private final SparseArray<VibrationEffect> mFallbackEffects;
private final SparseArray<Integer> mProcStatesCache = new SparseArray<>();
private final WorkSource mTmpWorkSource = new WorkSource();
private final Handler mH;
private final Object mLock = new Object();
+ private final VibratorController mVibratorController;
private final Context mContext;
private final PowerManager.WakeLock mWakeLock;
@@ -122,61 +107,21 @@ public class VibratorService extends IVibratorService.Stub
private final IBatteryStats mBatteryStatsService;
private final String mSystemUiPackage;
private PowerManagerInternal mPowerManagerInternal;
- private InputManager mIm;
private VibrationSettings mVibrationSettings;
private VibrationScaler mVibrationScaler;
+ private InputDeviceDelegate mInputDeviceDelegate;
- private final NativeWrapper mNativeWrapper;
private volatile VibrateWaveformThread mThread;
- // mInputDeviceVibrators lock should be acquired after mLock, if both are
- // to be acquired
- private final ArrayList<Vibrator> mInputDeviceVibrators = new ArrayList<>();
- private boolean mVibrateInputDevicesSetting; // guarded by mInputDeviceVibrators
- private boolean mInputDeviceListenerRegistered; // guarded by mInputDeviceVibrators
-
@GuardedBy("mLock")
private Vibration mCurrentVibration;
+ @GuardedBy("mLock")
+ private VibrationDeathRecipient mCurrentVibrationDeathRecipient;
private int mCurVibUid = -1;
private ExternalVibrationHolder mCurrentExternalVibration;
- private boolean mVibratorUnderExternalControl;
private boolean mLowPowerMode;
- @GuardedBy("mLock")
- private boolean mIsVibrating;
- @GuardedBy("mLock")
- private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners =
- new RemoteCallbackList<>();
private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>();
- static native long vibratorInit(OnCompleteListener listener);
-
- static native long vibratorGetFinalizer();
-
- static native boolean vibratorExists(long nativeServicePtr);
-
- static native void vibratorOn(long nativeServicePtr, long milliseconds, long vibrationId);
-
- static native void vibratorOff(long nativeServicePtr);
-
- static native void vibratorSetAmplitude(long nativeServicePtr, int amplitude);
-
- static native int[] vibratorGetSupportedEffects(long nativeServicePtr);
-
- static native int[] vibratorGetSupportedPrimitives(long nativeServicePtr);
-
- static native long vibratorPerformEffect(
- long nativeServicePtr, long effect, long strength, long vibrationId);
-
- static native void vibratorPerformComposedEffect(long nativeServicePtr,
- VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId);
-
- static native void vibratorSetExternalControl(long nativeServicePtr, boolean enabled);
-
- static native long vibratorGetCapabilities(long nativeServicePtr);
- static native void vibratorAlwaysOnEnable(long nativeServicePtr, long id, long effect,
- long strength);
- static native void vibratorAlwaysOnDisable(long nativeServicePtr, long id);
-
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
int capability) {
@@ -187,118 +132,65 @@ public class VibratorService extends IVibratorService.Stub
mProcStatesCache.delete(uid);
}
- @Override public void onUidActive(int uid) {
+ @Override
+ public void onUidActive(int uid) {
}
- @Override public void onUidIdle(int uid, boolean disabled) {
+ @Override
+ public void onUidIdle(int uid, boolean disabled) {
}
- @Override public void onUidCachedChanged(int uid, boolean cached) {
+ @Override
+ public void onUidCachedChanged(int uid, boolean cached) {
}
};
- /** Listener for vibration completion callbacks from native. */
- public interface OnCompleteListener {
+ /**
+ * Implementation of {@link OnVibrationCompleteListener} with a weak reference to this service.
+ */
+ private static final class VibrationCompleteListener implements OnVibrationCompleteListener {
+ private WeakReference<VibratorService> mServiceRef;
+
+ VibrationCompleteListener(VibratorService service) {
+ mServiceRef = new WeakReference<>(service);
+ }
- /** Callback triggered when vibration is complete, identified by {@link Vibration#id}. */
- void onComplete(long vibrationId);
+ @Override
+ public void onComplete(int vibratorId, long vibrationId) {
+ VibratorService service = mServiceRef.get();
+ if (service != null) {
+ service.onVibrationComplete(vibrationId);
+ }
+ }
}
- /** Holder for a {@link VibrationEffect}. */
- private final class Vibration implements IBinder.DeathRecipient {
-
- public final IBinder token;
- // Start time in CLOCK_BOOTTIME base.
- public final long startTime;
- public final VibrationAttributes attrs;
- public final long id;
- public final int uid;
- public final String opPkg;
- public final String reason;
-
- // The actual effect to be played.
- public VibrationEffect effect;
- // The original effect that was requested. Typically these two things differ because
- // the effect was scaled based on the users vibration intensity settings.
- public VibrationEffect originalEffect;
- // The scale applied to the original effect.
- public float scale;
-
- // Start/end times in unix epoch time. Only to be used for debugging purposes and to
- // correlate with other system events, any duration calculations should be done use
- // startTime so as not to be affected by discontinuities created by RTC adjustments.
- private final long mStartTimeDebug;
- private long mEndTimeDebug;
- private VibrationInfo.Status mStatus;
-
- private Vibration(IBinder token, VibrationEffect effect,
- VibrationAttributes attrs, int uid, String opPkg, String reason) {
- this.token = token;
- this.effect = effect;
- this.id = mNextVibrationId.getAndIncrement();
- this.startTime = SystemClock.elapsedRealtime();
- this.attrs = attrs;
- this.uid = uid;
- this.opPkg = opPkg;
- this.reason = reason;
- mStartTimeDebug = System.currentTimeMillis();
- mStatus = VibrationInfo.Status.RUNNING;
+ /** Death recipient to bind {@link Vibration}. */
+ private final class VibrationDeathRecipient implements IBinder.DeathRecipient {
+
+ private final Vibration mVibration;
+
+ private VibrationDeathRecipient(Vibration vibration) {
+ mVibration = vibration;
}
@Override
public void binderDied() {
synchronized (mLock) {
- if (this == mCurrentVibration) {
+ if (mVibration == mCurrentVibration) {
if (DEBUG) {
Slog.d(TAG, "Vibration finished because binder died, cleaning up");
}
- doCancelVibrateLocked(VibrationInfo.Status.CANCELLED);
+ doCancelVibrateLocked(Vibration.Status.CANCELLED);
}
}
}
- public void end(VibrationInfo.Status status) {
- if (hasEnded()) {
- // Vibration already ended, keep first ending status set and ignore this one.
- return;
- }
- mStatus = status;
- mEndTimeDebug = System.currentTimeMillis();
- }
-
- public boolean hasEnded() {
- return mStatus != VibrationInfo.Status.RUNNING;
- }
-
- public boolean hasTimeoutLongerThan(long millis) {
- final long duration = effect.getDuration();
- return duration >= 0 && duration > millis;
- }
-
- public boolean isHapticFeedback() {
- return VibratorService.this.isHapticFeedback(attrs.getUsage());
- }
-
- public boolean isNotification() {
- return VibratorService.this.isNotification(attrs.getUsage());
+ private void linkToDeath() throws RemoteException {
+ mVibration.token.linkToDeath(this, 0);
}
- public boolean isRingtone() {
- return VibratorService.this.isRingtone(attrs.getUsage());
- }
-
- public boolean isAlarm() {
- return VibratorService.this.isAlarm(attrs.getUsage());
- }
-
- public boolean isFromSystem() {
- return uid == Process.SYSTEM_UID || uid == 0 || mSystemUiPackage.equals(opPkg);
- }
-
- public VibrationInfo toInfo() {
- return new VibrationInfo(
- mStartTimeDebug, mEndTimeDebug, effect, originalEffect, scale, attrs,
- uid, opPkg, reason, mStatus);
+ private void unlinkToDeath() {
+ mVibration.token.unlinkToDeath(this, 0);
}
}
@@ -310,17 +202,17 @@ public class VibratorService extends IVibratorService.Stub
private final long mStartTimeDebug;
private long mEndTimeDebug;
- private VibrationInfo.Status mStatus;
+ private Vibration.Status mStatus;
private ExternalVibrationHolder(ExternalVibration externalVibration) {
this.externalVibration = externalVibration;
this.scale = IExternalVibratorService.SCALE_NONE;
mStartTimeDebug = System.currentTimeMillis();
- mStatus = VibrationInfo.Status.RUNNING;
+ mStatus = Vibration.Status.RUNNING;
}
- public void end(VibrationInfo.Status status) {
- if (mStatus != VibrationInfo.Status.RUNNING) {
+ public void end(Vibration.Status status) {
+ if (mStatus != Vibration.Status.RUNNING) {
// Vibration already ended, keep first ending status set and ignore this one.
return;
}
@@ -328,8 +220,8 @@ public class VibratorService extends IVibratorService.Stub
mEndTimeDebug = System.currentTimeMillis();
}
- public VibrationInfo toInfo() {
- return new VibrationInfo(
+ public Vibration.DebugInfo getDebugInfo() {
+ return new Vibration.DebugInfo(
mStartTimeDebug, mEndTimeDebug, /* effect= */ null, /* originalEffect= */ null,
scale, externalVibration.getVibrationAttributes(),
externalVibration.getUid(), externalVibration.getPackage(),
@@ -337,176 +229,19 @@ public class VibratorService extends IVibratorService.Stub
}
}
- /** Debug information about vibrations. */
- private static class VibrationInfo {
-
- public enum Status {
- RUNNING,
- FINISHED,
- CANCELLED,
- ERROR_APP_OPS,
- IGNORED,
- IGNORED_APP_OPS,
- IGNORED_BACKGROUND,
- IGNORED_RINGTONE,
- IGNORED_UNKNOWN_VIBRATION,
- IGNORED_UNSUPPORTED,
- IGNORED_FOR_ALARM,
- IGNORED_FOR_EXTERNAL,
- IGNORED_FOR_ONGOING,
- IGNORED_FOR_POWER,
- IGNORED_FOR_SETTINGS,
- }
-
- private final long mStartTimeDebug;
- private final long mEndTimeDebug;
- private final VibrationEffect mEffect;
- private final VibrationEffect mOriginalEffect;
- private final float mScale;
- private final VibrationAttributes mAttrs;
- private final int mUid;
- private final String mOpPkg;
- private final String mReason;
- private final VibrationInfo.Status mStatus;
-
- VibrationInfo(long startTimeDebug, long endTimeDebug, VibrationEffect effect,
- VibrationEffect originalEffect, float scale, VibrationAttributes attrs,
- int uid, String opPkg, String reason, VibrationInfo.Status status) {
- mStartTimeDebug = startTimeDebug;
- mEndTimeDebug = endTimeDebug;
- mEffect = effect;
- mOriginalEffect = originalEffect;
- mScale = scale;
- mAttrs = attrs;
- mUid = uid;
- mOpPkg = opPkg;
- mReason = reason;
- mStatus = status;
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("startTime: ")
- .append(DEBUG_DATE_FORMAT.format(new Date(mStartTimeDebug)))
- .append(", endTime: ")
- .append(mEndTimeDebug == 0 ? null
- : DEBUG_DATE_FORMAT.format(new Date(mEndTimeDebug)))
- .append(", status: ")
- .append(mStatus.name().toLowerCase())
- .append(", effect: ")
- .append(mEffect)
- .append(", originalEffect: ")
- .append(mOriginalEffect)
- .append(", scale: ")
- .append(String.format("%.2f", mScale))
- .append(", attrs: ")
- .append(mAttrs)
- .append(", uid: ")
- .append(mUid)
- .append(", opPkg: ")
- .append(mOpPkg)
- .append(", reason: ")
- .append(mReason)
- .toString();
- }
-
- void dumpProto(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(VibrationProto.START_TIME, mStartTimeDebug);
- proto.write(VibrationProto.END_TIME, mEndTimeDebug);
- proto.write(VibrationProto.STATUS, mStatus.ordinal());
-
- final long attrsToken = proto.start(VibrationProto.ATTRIBUTES);
- proto.write(VibrationAttributesProto.USAGE, mAttrs.getUsage());
- proto.write(VibrationAttributesProto.AUDIO_USAGE, mAttrs.getAudioUsage());
- proto.write(VibrationAttributesProto.FLAGS, mAttrs.getFlags());
- proto.end(attrsToken);
-
- if (mEffect != null) {
- dumpEffect(proto, VibrationProto.EFFECT, mEffect);
- }
- if (mOriginalEffect != null) {
- dumpEffect(proto, VibrationProto.ORIGINAL_EFFECT, mOriginalEffect);
- }
-
- proto.end(token);
- }
-
- private void dumpEffect(ProtoOutputStream proto, long fieldId, VibrationEffect effect) {
- final long token = proto.start(fieldId);
- if (effect instanceof VibrationEffect.OneShot) {
- dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect);
- } else if (effect instanceof VibrationEffect.Waveform) {
- dumpEffect(proto, VibrationEffectProto.WAVEFORM, (VibrationEffect.Waveform) effect);
- } else if (effect instanceof VibrationEffect.Prebaked) {
- dumpEffect(proto, VibrationEffectProto.PREBAKED, (VibrationEffect.Prebaked) effect);
- } else if (effect instanceof VibrationEffect.Composed) {
- dumpEffect(proto, VibrationEffectProto.COMPOSED, (VibrationEffect.Composed) effect);
- }
- proto.end(token);
- }
-
- private void dumpEffect(ProtoOutputStream proto, long fieldId,
- VibrationEffect.OneShot effect) {
- final long token = proto.start(fieldId);
- proto.write(OneShotProto.DURATION, (int) effect.getDuration());
- proto.write(OneShotProto.AMPLITUDE, effect.getAmplitude());
- proto.end(token);
- }
-
- private void dumpEffect(ProtoOutputStream proto, long fieldId,
- VibrationEffect.Waveform effect) {
- final long token = proto.start(fieldId);
- for (long timing : effect.getTimings()) {
- proto.write(WaveformProto.TIMINGS, (int) timing);
- }
- for (int amplitude : effect.getAmplitudes()) {
- proto.write(WaveformProto.AMPLITUDES, amplitude);
- }
- proto.write(WaveformProto.REPEAT, effect.getRepeatIndex() >= 0);
- proto.end(token);
- }
-
- private void dumpEffect(ProtoOutputStream proto, long fieldId,
- VibrationEffect.Prebaked effect) {
- final long token = proto.start(fieldId);
- proto.write(PrebakedProto.EFFECT_ID, effect.getId());
- proto.write(PrebakedProto.EFFECT_STRENGTH, effect.getEffectStrength());
- proto.write(PrebakedProto.FALLBACK, effect.shouldFallback());
- proto.end(token);
- }
-
- private void dumpEffect(ProtoOutputStream proto, long fieldId,
- VibrationEffect.Composed effect) {
- final long token = proto.start(fieldId);
- for (PrimitiveEffect primitive : effect.getPrimitiveEffects()) {
- proto.write(ComposedProto.EFFECT_IDS, primitive.id);
- proto.write(ComposedProto.EFFECT_SCALES, primitive.scale);
- proto.write(ComposedProto.DELAYS, primitive.delay);
- }
- proto.end(token);
- }
- }
-
VibratorService(Context context) {
this(context, new Injector());
}
@VisibleForTesting
VibratorService(Context context, Injector injector) {
- mNativeWrapper = injector.getNativeWrapper();
mH = injector.createHandler(Looper.myLooper());
-
- mNativeWrapper.vibratorInit(this::onVibrationComplete);
+ mVibratorController = injector.createVibratorController(
+ new VibrationCompleteListener(this));
// Reset the hardware to a default state, in case this is a runtime
// restart instead of a fresh boot.
- mNativeWrapper.vibratorOff();
-
- mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects());
- mSupportedPrimitives = asList(mNativeWrapper.vibratorGetSupportedPrimitives());
- mCapabilities = mNativeWrapper.vibratorGetCapabilities();
+ mVibratorController.off();
mContext = context;
PowerManager pm = context.getSystemService(PowerManager.class);
@@ -522,12 +257,6 @@ public class VibratorService extends IVibratorService.Stub
mPreviousVibrationsLimit = mContext.getResources().getInteger(
com.android.internal.R.integer.config_previousVibrationsDumpLimit);
- mDefaultVibrationAmplitude = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_defaultVibrationAmplitude);
-
- mAllowPriorityVibrationsInLowPowerMode = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_allowPriorityVibrationsInLowPowerMode);
-
mPreviousRingVibrations = new LinkedList<>();
mPreviousNotificationVibrations = new LinkedList<>();
mPreviousAlarmVibrations = new LinkedList<>();
@@ -538,48 +267,15 @@ public class VibratorService extends IVibratorService.Stub
filter.addAction(Intent.ACTION_SCREEN_OFF);
context.registerReceiver(mIntentReceiver, filter);
- VibrationEffect clickEffect = createEffectFromResource(
- com.android.internal.R.array.config_virtualKeyVibePattern);
- VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
- DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS, -1 /*repeatIndex*/);
- VibrationEffect heavyClickEffect = createEffectFromResource(
- com.android.internal.R.array.config_longPressVibePattern);
- VibrationEffect tickEffect = createEffectFromResource(
- com.android.internal.R.array.config_clockTickVibePattern);
-
- mFallbackEffects = new SparseArray<>();
- mFallbackEffects.put(VibrationEffect.EFFECT_CLICK, clickEffect);
- mFallbackEffects.put(VibrationEffect.EFFECT_DOUBLE_CLICK, doubleClickEffect);
- mFallbackEffects.put(VibrationEffect.EFFECT_TICK, tickEffect);
- mFallbackEffects.put(VibrationEffect.EFFECT_HEAVY_CLICK, heavyClickEffect);
-
- mFallbackEffects.put(VibrationEffect.EFFECT_TEXTURE_TICK,
- VibrationEffect.get(VibrationEffect.EFFECT_TICK, false));
-
injector.addService(EXTERNAL_VIBRATOR_SERVICE, new ExternalVibratorService());
}
- private VibrationEffect createEffectFromResource(int resId) {
- long[] timings = getLongIntArray(mContext.getResources(), resId);
- return createEffectFromTimings(timings);
- }
-
- private static VibrationEffect createEffectFromTimings(long[] timings) {
- if (timings == null || timings.length == 0) {
- return null;
- } else if (timings.length == 1) {
- return VibrationEffect.createOneShot(timings[0], VibrationEffect.DEFAULT_AMPLITUDE);
- } else {
- return VibrationEffect.createWaveform(timings, -1);
- }
- }
-
public void systemReady() {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorService#systemReady");
try {
- mIm = mContext.getSystemService(InputManager.class);
mVibrationSettings = new VibrationSettings(mContext, mH);
mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings);
+ mInputDeviceDelegate = new InputDeviceDelegate(mContext, mH);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mPowerManagerInternal.registerLowPowerModeObserver(
@@ -626,14 +322,19 @@ public class VibratorService extends IVibratorService.Stub
if (DEBUG) {
Slog.d(TAG, "Vibration finished by callback, cleaning up");
}
- doCancelVibrateLocked(VibrationInfo.Status.FINISHED);
+ doCancelVibrateLocked(Vibration.Status.FINISHED);
}
}
}
@Override // Binder call
public boolean hasVibrator() {
- return doVibratorExists();
+ // For now, we choose to ignore the presence of input devices that have vibrators
+ // when reporting whether the device has a vibrator. Applications often use this
+ // information to decide whether to enable certain features so they expect the
+ // result of hasVibrator() to be constant. For now, just report whether
+ // the device has a built-in vibrator.
+ return mVibratorController.isAvailable();
}
@Override // Binder call
@@ -641,32 +342,7 @@ public class VibratorService extends IVibratorService.Stub
if (!hasPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)) {
throw new SecurityException("Requires ACCESS_VIBRATOR_STATE permission");
}
- synchronized (mLock) {
- return mIsVibrating;
- }
- }
-
- @GuardedBy("mLock")
- private void notifyStateListenerLocked(IVibratorStateListener listener) {
- try {
- listener.onVibrating(mIsVibrating);
- } catch (RemoteException | RuntimeException e) {
- Slog.e(TAG, "Vibrator callback failed to call", e);
- }
- }
-
- @GuardedBy("mLock")
- private void notifyStateListenersLocked() {
- final int length = mVibratorStateListeners.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- final IVibratorStateListener listener =
- mVibratorStateListeners.getBroadcastItem(i);
- notifyStateListenerLocked(listener);
- }
- } finally {
- mVibratorStateListeners.finishBroadcast();
- }
+ return mVibratorController.isVibrating();
}
@Override // Binder call
@@ -674,19 +350,7 @@ public class VibratorService extends IVibratorService.Stub
if (!hasPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)) {
throw new SecurityException("Requires ACCESS_VIBRATOR_STATE permission");
}
- synchronized (mLock) {
- final long token = Binder.clearCallingIdentity();
- try {
- if (!mVibratorStateListeners.register(listener)) {
- return false;
- }
- // Notify its callback after new client registered.
- notifyStateListenerLocked(listener);
- return true;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
+ return mVibratorController.registerVibratorStateListener(listener);
}
@Override // Binder call
@@ -695,54 +359,26 @@ public class VibratorService extends IVibratorService.Stub
if (!hasPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)) {
throw new SecurityException("Requires ACCESS_VIBRATOR_STATE permission");
}
- synchronized (mLock) {
- final long token = Binder.clearCallingIdentity();
- try {
- return mVibratorStateListeners.unregister(listener);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
+ return mVibratorController.unregisterVibratorStateListener(listener);
}
@Override // Binder call
public boolean hasAmplitudeControl() {
- synchronized (mInputDeviceVibrators) {
- // Input device vibrators don't support amplitude controls yet, but are still used over
- // the system vibrator when connected.
- return hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)
- && mInputDeviceVibrators.isEmpty();
- }
+ // Input device vibrators always support amplitude controls.
+ return mInputDeviceDelegate.isAvailable()
+ || mVibratorController.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL);
}
@Override // Binder call
public int[] areEffectsSupported(int[] effectIds) {
- int[] supported = new int[effectIds.length];
- if (mSupportedEffects == null) {
- Arrays.fill(supported, Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN);
- } else {
- for (int i = 0; i < effectIds.length; i++) {
- supported[i] = mSupportedEffects.contains(effectIds[i])
- ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES
- : Vibrator.VIBRATION_EFFECT_SUPPORT_NO;
- }
- }
- return supported;
+ return mVibratorController.areEffectsSupported(effectIds);
}
@Override // Binder call
public boolean[] arePrimitivesSupported(int[] primitiveIds) {
- boolean[] supported = new boolean[primitiveIds.length];
- if (!hasCapability(IVibrator.CAP_COMPOSE_EFFECTS) || mSupportedPrimitives == null) {
- return supported;
- }
- for (int i = 0; i < primitiveIds.length; i++) {
- supported[i] = mSupportedPrimitives.contains(primitiveIds[i]);
- }
- return supported;
+ return mVibratorController.arePrimitivesSupported(primitiveIds);
}
-
private static List<Integer> asList(int... vals) {
if (vals == null) {
return null;
@@ -760,14 +396,14 @@ public class VibratorService extends IVibratorService.Stub
if (!hasPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON)) {
throw new SecurityException("Requires VIBRATE_ALWAYS_ON permission");
}
- if (!hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
+ if (!mVibratorController.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
Slog.e(TAG, "Always-on effects not supported.");
return false;
}
if (effect == null) {
synchronized (mLock) {
mAlwaysOnEffects.delete(alwaysOnId);
- mNativeWrapper.vibratorAlwaysOnDisable(alwaysOnId);
+ mVibratorController.updateAlwaysOn(alwaysOnId, /* effect= */ null);
}
} else {
if (!verifyVibrationEffect(effect)) {
@@ -779,7 +415,8 @@ public class VibratorService extends IVibratorService.Stub
}
attrs = fixupVibrationAttributes(attrs);
synchronized (mLock) {
- Vibration vib = new Vibration(null, effect, attrs, uid, opPkg, null);
+ Vibration vib = new Vibration(null, mNextVibrationId.getAndIncrement(), effect,
+ attrs, uid, opPkg, null);
mAlwaysOnEffects.put(alwaysOnId, vib);
updateAlwaysOnLocked(alwaysOnId, vib);
}
@@ -839,18 +476,6 @@ public class VibratorService extends IVibratorService.Stub
return attrs;
}
- private static long[] getLongIntArray(Resources r, int resid) {
- int[] ar = r.getIntArray(resid);
- if (ar == null) {
- return null;
- }
- long[] out = new long[ar.length];
- for (int i = 0; i < ar.length; i++) {
- out[i] = ar[i];
- }
- return out;
- }
-
@Override // Binder call
public void vibrate(int uid, String opPkg, VibrationEffect effect,
@Nullable VibrationAttributes attrs, String reason, IBinder token) {
@@ -869,24 +494,26 @@ public class VibratorService extends IVibratorService.Stub
}
attrs = fixupVibrationAttributes(attrs);
- Vibration vib = new Vibration(token, effect, attrs, uid, opPkg, reason);
+ Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
+ uid, opPkg, reason);
// If our current vibration is longer than the new vibration and is the same amplitude,
// then just let the current one finish.
synchronized (mLock) {
+ VibrationEffect currentEffect =
+ mCurrentVibration == null ? null : mCurrentVibration.getEffect();
if (effect instanceof VibrationEffect.OneShot
- && mCurrentVibration != null
- && mCurrentVibration.effect instanceof VibrationEffect.OneShot) {
+ && currentEffect instanceof VibrationEffect.OneShot) {
VibrationEffect.OneShot newOneShot = (VibrationEffect.OneShot) effect;
VibrationEffect.OneShot currentOneShot =
- (VibrationEffect.OneShot) mCurrentVibration.effect;
- if (mCurrentVibration.hasTimeoutLongerThan(newOneShot.getDuration())
+ (VibrationEffect.OneShot) currentEffect;
+ if (currentOneShot.getDuration() > newOneShot.getDuration()
&& newOneShot.getAmplitude() == currentOneShot.getAmplitude()) {
if (DEBUG) {
Slog.d(TAG,
"Ignoring incoming vibration in favor of current vibration");
}
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_ONGOING);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_ONGOING);
return;
}
}
@@ -898,7 +525,7 @@ public class VibratorService extends IVibratorService.Stub
if (DEBUG) {
Slog.d(TAG, "Ignoring incoming vibration for current external vibration");
}
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_EXTERNAL);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_EXTERNAL);
return;
}
@@ -908,32 +535,32 @@ public class VibratorService extends IVibratorService.Stub
// alarms, in favor of one-shot vibrations that are likely quite short.
if (!isRepeatingVibration(effect)
&& mCurrentVibration != null
- && isRepeatingVibration(mCurrentVibration.effect)) {
+ && isRepeatingVibration(currentEffect)) {
if (DEBUG) {
Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
}
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_ALARM);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_ALARM);
return;
}
if (mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
> ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
- && !vib.isNotification() && !vib.isRingtone() && !vib.isAlarm()) {
+ && !isNotification(vib) && !isRingtone(vib) && !isAlarm(vib)) {
Slog.e(TAG, "Ignoring incoming vibration as process with"
+ " uid= " + uid + " is background,"
+ " attrs= " + vib.attrs);
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_BACKGROUND);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_BACKGROUND);
return;
}
- linkVibration(vib);
+ linkVibrationLocked(vib);
final long ident = Binder.clearCallingIdentity();
try {
- doCancelVibrateLocked(VibrationInfo.Status.CANCELLED);
+ doCancelVibrateLocked(Vibration.Status.CANCELLED);
startVibrationLocked(vib);
if (!vib.hasEnded() && mCurrentVibration.id != vib.id) {
// Vibration was unexpectedly ignored: add to list for debugging
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED);
+ endVibrationLocked(vib, Vibration.Status.IGNORED);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -953,13 +580,13 @@ public class VibratorService extends IVibratorService.Stub
return effect.getDuration() == Long.MAX_VALUE;
}
- private void endVibrationLocked(Vibration vib, VibrationInfo.Status status) {
- final LinkedList<VibrationInfo> previousVibrations;
- if (vib.isRingtone()) {
+ private void endVibrationLocked(Vibration vib, Vibration.Status status) {
+ final LinkedList<Vibration.DebugInfo> previousVibrations;
+ if (isRingtone(vib)) {
previousVibrations = mPreviousRingVibrations;
- } else if (vib.isNotification()) {
+ } else if (isNotification(vib)) {
previousVibrations = mPreviousNotificationVibrations;
- } else if (vib.isAlarm()) {
+ } else if (isAlarm(vib)) {
previousVibrations = mPreviousAlarmVibrations;
} else {
previousVibrations = mPreviousVibrations;
@@ -969,15 +596,15 @@ public class VibratorService extends IVibratorService.Stub
previousVibrations.removeFirst();
}
vib.end(status);
- previousVibrations.addLast(vib.toInfo());
+ previousVibrations.addLast(vib.getDebugInfo());
}
- private void endVibrationLocked(ExternalVibrationHolder vib, VibrationInfo.Status status) {
+ private void endVibrationLocked(ExternalVibrationHolder vib, Vibration.Status status) {
if (mPreviousExternalVibrations.size() > mPreviousVibrationsLimit) {
mPreviousExternalVibrations.removeFirst();
}
vib.end(status);
- mPreviousExternalVibrations.addLast(vib.toInfo());
+ mPreviousExternalVibrations.addLast(vib.getDebugInfo());
}
@Override // Binder call
@@ -993,7 +620,7 @@ public class VibratorService extends IVibratorService.Stub
}
final long ident = Binder.clearCallingIdentity();
try {
- doCancelVibrateLocked(VibrationInfo.Status.CANCELLED);
+ doCancelVibrateLocked(Vibration.Status.CANCELLED);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1002,7 +629,7 @@ public class VibratorService extends IVibratorService.Stub
}
@GuardedBy("mLock")
- private void doCancelVibrateLocked(VibrationInfo.Status status) {
+ private void doCancelVibrateLocked(Vibration.Status status) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelVibrateLocked");
try {
@@ -1014,7 +641,7 @@ public class VibratorService extends IVibratorService.Stub
endVibrationLocked(mCurrentExternalVibration, status);
mCurrentExternalVibration.externalVibration.mute();
mCurrentExternalVibration = null;
- setVibratorUnderExternalControl(false);
+ mVibratorController.setExternalControl(false);
}
doVibratorOff();
reportFinishVibrationLocked(status);
@@ -1031,7 +658,7 @@ public class VibratorService extends IVibratorService.Stub
synchronized (mLock) {
// Make sure the vibration is really done. This also reports that the vibration is
// finished.
- doCancelVibrateLocked(VibrationInfo.Status.FINISHED);
+ doCancelVibrateLocked(Vibration.Status.FINISHED);
}
}
@@ -1055,23 +682,22 @@ public class VibratorService extends IVibratorService.Stub
try {
// Set current vibration before starting it, so callback will work.
mCurrentVibration = vib;
- if (vib.effect instanceof VibrationEffect.OneShot) {
+ VibrationEffect effect = vib.getEffect();
+ if (effect instanceof VibrationEffect.OneShot) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
doVibratorOn(vib);
- } else if (vib.effect instanceof VibrationEffect.Waveform) {
- // mThread better be null here. doCancelVibrate should always be
- // called before startNextVibrationLocked or startVibrationLocked.
- mThread = new VibrateWaveformThread(vib);
- mThread.start();
- } else if (vib.effect instanceof VibrationEffect.Prebaked) {
+ } else if (effect instanceof VibrationEffect.Waveform) {
+ Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
+ doVibratorWaveformEffectLocked(vib);
+ } else if (effect instanceof VibrationEffect.Prebaked) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
doVibratorPrebakedEffectLocked(vib);
- } else if (vib.effect instanceof VibrationEffect.Composed) {
+ } else if (effect instanceof VibrationEffect.Composed) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
doVibratorComposedEffectLocked(vib);
} else {
Slog.e(TAG, "Unknown vibration type, ignoring");
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_UNKNOWN_VIBRATION);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_UNKNOWN_VIBRATION);
// The set current vibration is not actually playing, so drop it.
mCurrentVibration = null;
}
@@ -1093,11 +719,7 @@ public class VibratorService extends IVibratorService.Stub
/** Scale the vibration effect by the intensity as appropriate based its intent. */
private void applyVibrationIntensityScalingLocked(Vibration vib) {
- VibrationEffect scaled = mVibrationScaler.scale(vib.effect, vib.attrs.getUsage());
- if (!scaled.equals(vib.effect)) {
- vib.originalEffect = vib.effect;
- vib.effect = scaled;
- }
+ vib.updateEffect(mVibrationScaler.scale(vib.getEffect(), vib.attrs.getUsage()));
}
private static boolean shouldBypassDnd(VibrationAttributes attrs) {
@@ -1123,21 +745,21 @@ public class VibratorService extends IVibratorService.Stub
private boolean shouldVibrate(Vibration vib) {
if (!shouldVibrateForPowerModeLocked(vib)) {
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_POWER);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_POWER);
return false;
}
int intensity = mVibrationSettings.getCurrentIntensity(vib.attrs.getUsage());
if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_SETTINGS);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_SETTINGS);
return false;
}
- if (vib.isRingtone() && !mVibrationSettings.shouldVibrateForRingtone()) {
+ if (isRingtone(vib) && !mVibrationSettings.shouldVibrateForRingtone()) {
if (DEBUG) {
Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones");
}
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_RINGTONE);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_RINGTONE);
return false;
}
@@ -1147,9 +769,9 @@ public class VibratorService extends IVibratorService.Stub
// We might be getting calls from within system_server, so we don't actually
// want to throw a SecurityException here.
Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid);
- endVibrationLocked(vib, VibrationInfo.Status.ERROR_APP_OPS);
+ endVibrationLocked(vib, Vibration.Status.ERROR_APP_OPS);
} else {
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_APP_OPS);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_APP_OPS);
}
return false;
}
@@ -1158,14 +780,14 @@ public class VibratorService extends IVibratorService.Stub
}
@GuardedBy("mLock")
- private void reportFinishVibrationLocked(VibrationInfo.Status status) {
+ private void reportFinishVibrationLocked(Vibration.Status status) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked");
try {
if (mCurrentVibration != null) {
endVibrationLocked(mCurrentVibration, status);
mAppOps.finishOp(AppOpsManager.OP_VIBRATE, mCurrentVibration.uid,
mCurrentVibration.opPkg);
- unlinkVibration(mCurrentVibration);
+ unlinkVibrationLocked();
mCurrentVibration = null;
}
} finally {
@@ -1173,73 +795,45 @@ public class VibratorService extends IVibratorService.Stub
}
}
- private void linkVibration(Vibration vib) {
+ @GuardedBy("mLock")
+ private void linkVibrationLocked(Vibration vib) {
+ // Unlink previously linked vibration, if any.
+ unlinkVibrationLocked();
// Only link against waveforms since they potentially don't have a finish if
// they're repeating. Let other effects just play out until they're done.
- if (vib.effect instanceof VibrationEffect.Waveform) {
+ if (vib.getEffect() instanceof VibrationEffect.Waveform) {
try {
- vib.token.linkToDeath(vib, 0);
+ mCurrentVibrationDeathRecipient = new VibrationDeathRecipient(vib);
+ mCurrentVibrationDeathRecipient.linkToDeath();
} catch (RemoteException e) {
return;
}
}
}
- private void unlinkVibration(Vibration vib) {
- if (vib.effect instanceof VibrationEffect.Waveform) {
- vib.token.unlinkToDeath(vib, 0);
+ @GuardedBy("mLock")
+ private void unlinkVibrationLocked() {
+ if (mCurrentVibrationDeathRecipient != null) {
+ mCurrentVibrationDeathRecipient.unlinkToDeath();
+ mCurrentVibrationDeathRecipient = null;
}
}
private void updateVibrators() {
synchronized (mLock) {
- boolean devicesUpdated = updateInputDeviceVibratorsLocked();
+ boolean devicesUpdated = mInputDeviceDelegate.updateInputDeviceVibrators(
+ mVibrationSettings.shouldVibrateInputDevices());
boolean lowPowerModeUpdated = updateLowPowerModeLocked();
if (devicesUpdated || lowPowerModeUpdated) {
// If the state changes out from under us then just reset.
- doCancelVibrateLocked(VibrationInfo.Status.CANCELLED);
+ doCancelVibrateLocked(Vibration.Status.CANCELLED);
}
updateAlwaysOnLocked();
}
}
- private boolean updateInputDeviceVibratorsLocked() {
- boolean changed = false;
- boolean vibrateInputDevices = mVibrationSettings.shouldVibrateInputDevices();
- if (vibrateInputDevices != mVibrateInputDevicesSetting) {
- changed = true;
- mVibrateInputDevicesSetting = vibrateInputDevices;
- }
-
- if (mVibrateInputDevicesSetting) {
- if (!mInputDeviceListenerRegistered) {
- mInputDeviceListenerRegistered = true;
- mIm.registerInputDeviceListener(this, mH);
- }
- } else {
- if (mInputDeviceListenerRegistered) {
- mInputDeviceListenerRegistered = false;
- mIm.unregisterInputDeviceListener(this);
- }
- }
-
- mInputDeviceVibrators.clear();
- if (mVibrateInputDevicesSetting) {
- int[] ids = mIm.getInputDeviceIds();
- for (int i = 0; i < ids.length; i++) {
- InputDevice device = mIm.getInputDevice(ids[i]);
- Vibrator vibrator = device.getVibrator();
- if (vibrator.hasVibrator()) {
- mInputDeviceVibrators.add(vibrator);
- }
- }
- return true;
- }
- return changed;
- }
-
private boolean updateLowPowerModeLocked() {
boolean lowPowerMode = mPowerManagerInternal
.getLowPowerState(ServiceType.VIBRATION).batterySaverEnabled;
@@ -1251,13 +845,13 @@ public class VibratorService extends IVibratorService.Stub
}
private void updateAlwaysOnLocked(int id, Vibration vib) {
+ VibrationEffect.Prebaked effect;
if (!shouldVibrate(vib)) {
- mNativeWrapper.vibratorAlwaysOnDisable(id);
+ effect = null;
} else {
- VibrationEffect.Prebaked scaled = mVibrationScaler.scale(vib.effect,
- vib.attrs.getUsage());
- mNativeWrapper.vibratorAlwaysOnEnable(id, scaled.getId(), scaled.getEffectStrength());
+ effect = mVibrationScaler.scale(vib.getEffect(), vib.attrs.getUsage());
}
+ mVibratorController.updateAlwaysOn(id, effect);
}
private void updateAlwaysOnLocked() {
@@ -1268,85 +862,64 @@ public class VibratorService extends IVibratorService.Stub
}
}
- @Override
- public void onInputDeviceAdded(int deviceId) {
- updateVibrators();
- }
-
- @Override
- public void onInputDeviceChanged(int deviceId) {
- updateVibrators();
- }
-
- @Override
- public void onInputDeviceRemoved(int deviceId) {
- updateVibrators();
- }
-
- private boolean doVibratorExists() {
- // For now, we choose to ignore the presence of input devices that have vibrators
- // when reporting whether the device has a vibrator. Applications often use this
- // information to decide whether to enable certain features so they expect the
- // result of hasVibrator() to be constant. For now, just report whether
- // the device has a built-in vibrator.
- //synchronized (mInputDeviceVibrators) {
- // return !mInputDeviceVibrators.isEmpty() || vibratorExists();
- //}
- return mNativeWrapper.vibratorExists();
- }
-
private void doVibratorOn(Vibration vib) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
try {
- synchronized (mInputDeviceVibrators) {
- final VibrationEffect.OneShot oneShot = vib.effect.resolve(
- mDefaultVibrationAmplitude);
- if (DEBUG) {
- Slog.d(TAG, "Turning vibrator on for " + oneShot.getDuration() + " ms"
- + " with amplitude " + oneShot.getAmplitude() + ".");
- }
+ final VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.getEffect();
+ if (DEBUG) {
+ Slog.d(TAG, "Turning vibrator on for " + oneShot.getDuration() + " ms"
+ + " with amplitude " + oneShot.getAmplitude() + ".");
+ }
+ boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
+ vib.uid, vib.opPkg, oneShot, vib.reason, vib.attrs);
+ if (inputDevicesAvailable) {
+ // The set current vibration is no longer being played by this service, so drop it.
+ mCurrentVibration = null;
+ endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
+ } else {
noteVibratorOnLocked(vib.uid, oneShot.getDuration());
- final int vibratorCount = mInputDeviceVibrators.size();
- if (vibratorCount != 0) {
- for (int i = 0; i < vibratorCount; i++) {
- mInputDeviceVibrators.get(i).vibrate(vib.uid, vib.opPkg, oneShot,
- vib.reason, vib.attrs);
- }
- } else {
- // Note: ordering is important here! Many haptic drivers will reset their
- // amplitude when enabled, so we always have to enable first, then set the
- // amplitude.
- mNativeWrapper.vibratorOn(oneShot.getDuration(), vib.id);
- doVibratorSetAmplitude(oneShot.getAmplitude());
- }
+ // Note: ordering is important here! Many haptic drivers will reset their
+ // amplitude when enabled, so we always have to enable first, then set the
+ // amplitude.
+ mVibratorController.on(oneShot.getDuration(), vib.id);
+ mVibratorController.setAmplitude(oneShot.getAmplitude());
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
- private void doVibratorSetAmplitude(int amplitude) {
- if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
- mNativeWrapper.vibratorSetAmplitude(amplitude);
+ private void doVibratorOff() {
+ Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff");
+ try {
+ if (DEBUG) {
+ Slog.d(TAG, "Turning vibrator off.");
+ }
+ noteVibratorOffLocked();
+ boolean inputDevicesAvailable = mInputDeviceDelegate.cancelVibrateIfAvailable();
+ if (!inputDevicesAvailable) {
+ mVibratorController.off();
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
- private void doVibratorOff() {
- Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff");
+ @GuardedBy("mLock")
+ private void doVibratorWaveformEffectLocked(Vibration vib) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorWaveformEffectLocked");
try {
- synchronized (mInputDeviceVibrators) {
- if (DEBUG) {
- Slog.d(TAG, "Turning vibrator off.");
- }
- noteVibratorOffLocked();
- final int vibratorCount = mInputDeviceVibrators.size();
- if (vibratorCount != 0) {
- for (int i = 0; i < vibratorCount; i++) {
- mInputDeviceVibrators.get(i).cancel();
- }
- } else {
- mNativeWrapper.vibratorOff();
- }
+ boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
+ vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs);
+ if (inputDevicesAvailable) {
+ // The set current vibration is no longer being played by this service, so drop it.
+ mCurrentVibration = null;
+ endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
+ } else {
+ // mThread better be null here. doCancelVibrate should always be
+ // called before startNextVibrationLocked or startVibrationLocked.
+ mThread = new VibrateWaveformThread(vib);
+ mThread.start();
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -1357,37 +930,33 @@ public class VibratorService extends IVibratorService.Stub
private void doVibratorPrebakedEffectLocked(Vibration vib) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorPrebakedEffectLocked");
try {
- final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect;
- final boolean usingInputDeviceVibrators;
- synchronized (mInputDeviceVibrators) {
- usingInputDeviceVibrators = !mInputDeviceVibrators.isEmpty();
- }
- // Input devices don't support prebaked effect, so skip trying it with them.
- if (!usingInputDeviceVibrators) {
- long duration = mNativeWrapper.vibratorPerformEffect(
- prebaked.getId(), prebaked.getEffectStrength(), vib.id);
+ final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.getEffect();
+ // Input devices don't support prebaked effect, so skip trying it with them and allow
+ // fallback to be attempted.
+ if (!mInputDeviceDelegate.isAvailable()) {
+ long duration = mVibratorController.on(prebaked, vib.id);
if (duration > 0) {
noteVibratorOnLocked(vib.uid, duration);
return;
}
}
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_UNSUPPORTED);
+ endVibrationLocked(vib, Vibration.Status.IGNORED_UNSUPPORTED);
// The set current vibration is not actually playing, so drop it.
mCurrentVibration = null;
if (!prebaked.shouldFallback()) {
return;
}
- VibrationEffect effect = getFallbackEffect(prebaked.getId());
+ VibrationEffect effect = mVibrationSettings.getFallbackEffect(prebaked.getId());
if (effect == null) {
Slog.w(TAG, "Failed to play prebaked effect, no fallback");
return;
}
- Vibration fallbackVib = new Vibration(vib.token, effect, vib.attrs, vib.uid,
- vib.opPkg, vib.reason + " (fallback)");
+ Vibration fallbackVib = new Vibration(vib.token, mNextVibrationId.getAndIncrement(),
+ effect, vib.attrs, vib.uid, vib.opPkg, vib.reason + " (fallback)");
// Set current vibration before starting it, so callback will work.
mCurrentVibration = fallbackVib;
- linkVibration(fallbackVib);
+ linkVibrationLocked(fallbackVib);
applyVibrationIntensityScalingLocked(fallbackVib);
startVibrationInnerLocked(fallbackVib);
} finally {
@@ -1400,53 +969,49 @@ public class VibratorService extends IVibratorService.Stub
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorComposedEffectLocked");
try {
- final VibrationEffect.Composed composed = (VibrationEffect.Composed) vib.effect;
- final boolean usingInputDeviceVibrators;
- synchronized (mInputDeviceVibrators) {
- usingInputDeviceVibrators = !mInputDeviceVibrators.isEmpty();
- }
- // Input devices don't support composed effect, so skip trying it with them.
- if (usingInputDeviceVibrators || !hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
- endVibrationLocked(vib, VibrationInfo.Status.IGNORED_UNSUPPORTED);
+ final VibrationEffect.Composed composed = (VibrationEffect.Composed) vib.getEffect();
+ boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
+ vib.uid, vib.opPkg, composed, vib.reason, vib.attrs);
+ if (inputDevicesAvailable) {
+ // The set current vibration is no longer being played by this service, so drop it.
+ mCurrentVibration = null;
+ endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
+ return;
+ } else if (!mVibratorController.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
// The set current vibration is not actually playing, so drop it.
mCurrentVibration = null;
+ endVibrationLocked(vib, Vibration.Status.IGNORED_UNSUPPORTED);
return;
}
- PrimitiveEffect[] primitiveEffects =
- composed.getPrimitiveEffects().toArray(new PrimitiveEffect[0]);
- mNativeWrapper.vibratorPerformComposedEffect(primitiveEffects, vib.id);
+ mVibratorController.on(composed, vib.id);
// Composed effects don't actually give us an estimated duration, so we just guess here.
- noteVibratorOnLocked(vib.uid, 10 * primitiveEffects.length);
+ noteVibratorOnLocked(vib.uid, 10 * composed.getPrimitiveEffects().size());
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
- private boolean hasCapability(long capability) {
- return (mCapabilities & capability) == capability;
- }
-
- private VibrationEffect getFallbackEffect(int effectId) {
- return mFallbackEffects.get(effectId);
+ private static boolean isNotification(Vibration vib) {
+ return vib.attrs.getUsage() == VibrationAttributes.USAGE_NOTIFICATION;
}
- private static boolean isNotification(int usageHint) {
- return usageHint == VibrationAttributes.USAGE_NOTIFICATION;
+ private static boolean isRingtone(Vibration vib) {
+ return vib.attrs.getUsage() == VibrationAttributes.USAGE_RINGTONE;
}
- private static boolean isRingtone(int usageHint) {
- return usageHint == VibrationAttributes.USAGE_RINGTONE;
+ private static boolean isHapticFeedback(Vibration vib) {
+ return vib.attrs.getUsage() == VibrationAttributes.USAGE_TOUCH;
}
- private static boolean isHapticFeedback(int usageHint) {
- return usageHint == VibrationAttributes.USAGE_TOUCH;
+ private static boolean isAlarm(Vibration vib) {
+ return vib.attrs.getUsage() == VibrationAttributes.USAGE_ALARM;
}
- private static boolean isAlarm(int usageHint) {
- return usageHint == VibrationAttributes.USAGE_ALARM;
+ private boolean isFromSystem(Vibration vib) {
+ return vib.uid == Process.SYSTEM_UID || vib.uid == 0 || mSystemUiPackage.equals(vib.opPkg);
}
private void noteVibratorOnLocked(int uid, long millis) {
@@ -1455,10 +1020,6 @@ public class VibratorService extends IVibratorService.Stub
FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED, uid, null,
FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__ON, millis);
mCurVibUid = uid;
- if (!mIsVibrating) {
- mIsVibrating = true;
- notifyStateListenersLocked();
- }
} catch (RemoteException e) {
}
}
@@ -1472,22 +1033,6 @@ public class VibratorService extends IVibratorService.Stub
} catch (RemoteException e) { }
mCurVibUid = -1;
}
- if (mIsVibrating) {
- mIsVibrating = false;
- notifyStateListenersLocked();
- }
- }
-
- private void setVibratorUnderExternalControl(boolean externalControl) {
- if (DEBUG) {
- if (externalControl) {
- Slog.d(TAG, "Vibrator going under external control.");
- } else {
- Slog.d(TAG, "Taking back control of vibrator.");
- }
- }
- mVibratorUnderExternalControl = externalControl;
- mNativeWrapper.vibratorSetExternalControl(externalControl);
}
private void dumpInternal(PrintWriter pw) {
@@ -1495,48 +1040,43 @@ public class VibratorService extends IVibratorService.Stub
synchronized (mLock) {
pw.print(" mCurrentVibration=");
if (mCurrentVibration != null) {
- pw.println(mCurrentVibration.toInfo().toString());
+ pw.println(mCurrentVibration.getDebugInfo().toString());
} else {
pw.println("null");
}
pw.print(" mCurrentExternalVibration=");
if (mCurrentExternalVibration != null) {
- pw.println(mCurrentExternalVibration.toInfo().toString());
+ pw.println(mCurrentExternalVibration.getDebugInfo().toString());
} else {
pw.println("null");
}
- pw.println(" mVibratorUnderExternalControl=" + mVibratorUnderExternalControl);
- pw.println(" mIsVibrating=" + mIsVibrating);
- pw.println(" mVibratorStateListeners Count="
- + mVibratorStateListeners.getRegisteredCallbackCount());
pw.println(" mLowPowerMode=" + mLowPowerMode);
+ pw.println(" mVibratorController=" + mVibratorController);
pw.println(" mVibrationSettings=" + mVibrationSettings);
- pw.println(" mSupportedEffects=" + mSupportedEffects);
- pw.println(" mSupportedPrimitives=" + mSupportedPrimitives);
pw.println();
pw.println(" Previous ring vibrations:");
- for (VibrationInfo info : mPreviousRingVibrations) {
+ for (Vibration.DebugInfo info : mPreviousRingVibrations) {
pw.print(" ");
pw.println(info.toString());
}
pw.println(" Previous notification vibrations:");
- for (VibrationInfo info : mPreviousNotificationVibrations) {
+ for (Vibration.DebugInfo info : mPreviousNotificationVibrations) {
pw.println(" " + info);
}
pw.println(" Previous alarm vibrations:");
- for (VibrationInfo info : mPreviousAlarmVibrations) {
+ for (Vibration.DebugInfo info : mPreviousAlarmVibrations) {
pw.println(" " + info);
}
pw.println(" Previous vibrations:");
- for (VibrationInfo info : mPreviousVibrations) {
+ for (Vibration.DebugInfo info : mPreviousVibrations) {
pw.println(" " + info);
}
pw.println(" Previous external vibrations:");
- for (VibrationInfo info : mPreviousExternalVibrations) {
+ for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
pw.println(" " + info);
}
}
@@ -1547,16 +1087,16 @@ public class VibratorService extends IVibratorService.Stub
synchronized (mLock) {
if (mCurrentVibration != null) {
- mCurrentVibration.toInfo().dumpProto(proto,
+ mCurrentVibration.getDebugInfo().dumpProto(proto,
VibratorServiceDumpProto.CURRENT_VIBRATION);
}
if (mCurrentExternalVibration != null) {
- mCurrentExternalVibration.toInfo().dumpProto(proto,
+ mCurrentExternalVibration.getDebugInfo().dumpProto(proto,
VibratorServiceDumpProto.CURRENT_EXTERNAL_VIBRATION);
}
- proto.write(VibratorServiceDumpProto.IS_VIBRATING, mIsVibrating);
+ proto.write(VibratorServiceDumpProto.IS_VIBRATING, mVibratorController.isVibrating());
proto.write(VibratorServiceDumpProto.VIBRATOR_UNDER_EXTERNAL_CONTROL,
- mVibratorUnderExternalControl);
+ mVibratorController.isUnderExternalControl());
proto.write(VibratorServiceDumpProto.LOW_POWER_MODE, mLowPowerMode);
proto.write(VibratorServiceDumpProto.HAPTIC_FEEDBACK_INTENSITY,
mVibrationSettings.getCurrentIntensity(VibrationAttributes.USAGE_TOUCH));
@@ -1571,23 +1111,23 @@ public class VibratorService extends IVibratorService.Stub
proto.write(VibratorServiceDumpProto.RING_DEFAULT_INTENSITY,
mVibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_RINGTONE));
- for (VibrationInfo info : mPreviousRingVibrations) {
+ for (Vibration.DebugInfo info : mPreviousRingVibrations) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_RING_VIBRATIONS);
}
- for (VibrationInfo info : mPreviousNotificationVibrations) {
+ for (Vibration.DebugInfo info : mPreviousNotificationVibrations) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS);
}
- for (VibrationInfo info : mPreviousAlarmVibrations) {
+ for (Vibration.DebugInfo info : mPreviousAlarmVibrations) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS);
}
- for (VibrationInfo info : mPreviousVibrations) {
+ for (Vibration.DebugInfo info : mPreviousVibrations) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_VIBRATIONS);
}
- for (VibrationInfo info : mPreviousExternalVibrations) {
+ for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS);
}
}
@@ -1602,9 +1142,9 @@ public class VibratorService extends IVibratorService.Stub
private boolean mForceStop;
VibrateWaveformThread(Vibration vib) {
- mWaveform = (VibrationEffect.Waveform) vib.effect;
- mVibration = new Vibration(vib.token, /* effect= */ null, vib.attrs, vib.uid,
- vib.opPkg, vib.reason);
+ mWaveform = (VibrationEffect.Waveform) vib.getEffect();
+ mVibration = new Vibration(vib.token, /* id= */ 0, /* effect= */ null, vib.attrs,
+ vib.uid, vib.opPkg, vib.reason);
mTmpWorkSource.set(vib.uid);
mWakeLock.setWorkSource(mTmpWorkSource);
}
@@ -1676,13 +1216,13 @@ public class VibratorService extends IVibratorService.Stub
// appropriate intervals.
long onDuration = getTotalOnDuration(
timings, amplitudes, index - 1, repeat);
- mVibration.effect = VibrationEffect.createOneShot(
- onDuration, amplitude);
+ mVibration.updateEffect(
+ VibrationEffect.createOneShot(onDuration, amplitude));
doVibratorOn(mVibration);
nextVibratorStopTime = now + onDuration;
} else {
// Vibrator is already ON, so just change its amplitude.
- doVibratorSetAmplitude(amplitude);
+ mVibratorController.setAmplitude(amplitude);
}
} else {
// Previous vibration should have already finished, but we make sure
@@ -1744,95 +1284,12 @@ public class VibratorService extends IVibratorService.Stub
}
}
- /** Wrapper around the static-native methods of {@link VibratorService} for tests. */
- @VisibleForTesting
- public static class NativeWrapper {
-
- private long mNativeServicePtr = 0;
-
- /** Checks if vibrator exists on device. */
- public boolean vibratorExists() {
- return VibratorService.vibratorExists(mNativeServicePtr);
- }
-
- /** Initializes connection to vibrator HAL service. */
- public void vibratorInit(OnCompleteListener listener) {
- mNativeServicePtr = VibratorService.vibratorInit(listener);
- long finalizerPtr = VibratorService.vibratorGetFinalizer();
-
- if (finalizerPtr != 0) {
- NativeAllocationRegistry registry =
- NativeAllocationRegistry.createMalloced(
- VibratorService.class.getClassLoader(), finalizerPtr);
- registry.registerNativeAllocation(this, mNativeServicePtr);
- }
- }
-
- /** Turns vibrator on for given time. */
- public void vibratorOn(long milliseconds, long vibrationId) {
- VibratorService.vibratorOn(mNativeServicePtr, milliseconds, vibrationId);
- }
-
- /** Turns vibrator off. */
- public void vibratorOff() {
- VibratorService.vibratorOff(mNativeServicePtr);
- }
-
- /** Sets the amplitude for the vibrator to run. */
- public void vibratorSetAmplitude(int amplitude) {
- VibratorService.vibratorSetAmplitude(mNativeServicePtr, amplitude);
- }
-
- /** Returns all predefined effects supported by the device vibrator. */
- public int[] vibratorGetSupportedEffects() {
- return VibratorService.vibratorGetSupportedEffects(mNativeServicePtr);
- }
-
- /** Returns all compose primitives supported by the device vibrator. */
- public int[] vibratorGetSupportedPrimitives() {
- return VibratorService.vibratorGetSupportedPrimitives(mNativeServicePtr);
- }
-
- /** Turns vibrator on to perform one of the supported effects. */
- public long vibratorPerformEffect(long effect, long strength, long vibrationId) {
- return VibratorService.vibratorPerformEffect(
- mNativeServicePtr, effect, strength, vibrationId);
- }
-
- /** Turns vibrator on to perform one of the supported composed effects. */
- public void vibratorPerformComposedEffect(
- VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) {
- VibratorService.vibratorPerformComposedEffect(mNativeServicePtr, effect,
- vibrationId);
- }
-
- /** Enabled the device vibrator to be controlled by another service. */
- public void vibratorSetExternalControl(boolean enabled) {
- VibratorService.vibratorSetExternalControl(mNativeServicePtr, enabled);
- }
-
- /** Returns all capabilities of the device vibrator. */
- public long vibratorGetCapabilities() {
- return VibratorService.vibratorGetCapabilities(mNativeServicePtr);
- }
-
- /** Enable always-on vibration with given id and effect. */
- public void vibratorAlwaysOnEnable(long id, long effect, long strength) {
- VibratorService.vibratorAlwaysOnEnable(mNativeServicePtr, id, effect, strength);
- }
-
- /** Disable always-on vibration for given id. */
- public void vibratorAlwaysOnDisable(long id) {
- VibratorService.vibratorAlwaysOnDisable(mNativeServicePtr, id);
- }
- }
-
/** Point of injection for test dependencies */
@VisibleForTesting
static class Injector {
- NativeWrapper getNativeWrapper() {
- return new NativeWrapper();
+ VibratorController createVibratorController(OnVibrationCompleteListener listener) {
+ return new VibratorController(/* vibratorId= */ 0, listener);
}
Handler createHandler(Looper looper) {
@@ -1855,9 +1312,9 @@ public class VibratorService extends IVibratorService.Stub
// haptic feedback as part of the transition. So we don't cancel
// system vibrations.
if (mCurrentVibration != null
- && !(mCurrentVibration.isHapticFeedback()
- && mCurrentVibration.isFromSystem())) {
- doCancelVibrateLocked(VibrationInfo.Status.CANCELLED);
+ && !(isHapticFeedback(mCurrentVibration)
+ && isFromSystem(mCurrentVibration))) {
+ doCancelVibrateLocked(Vibration.Status.CANCELLED);
}
}
}
@@ -1898,7 +1355,7 @@ public class VibratorService extends IVibratorService.Stub
@Override
public int onExternalVibrationStart(ExternalVibration vib) {
- if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
+ if (!mVibratorController.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
return IExternalVibratorService.SCALE_MUTE;
}
if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE,
@@ -1916,9 +1373,9 @@ public class VibratorService extends IVibratorService.Stub
vibHolder.scale = SCALE_MUTE;
if (mode == AppOpsManager.MODE_ERRORED) {
Slog.w(TAG, "Would be an error: external vibrate from uid " + vib.getUid());
- endVibrationLocked(vibHolder, VibrationInfo.Status.ERROR_APP_OPS);
+ endVibrationLocked(vibHolder, Vibration.Status.ERROR_APP_OPS);
} else {
- endVibrationLocked(vibHolder, VibrationInfo.Status.IGNORED_APP_OPS);
+ endVibrationLocked(vibHolder, Vibration.Status.IGNORED_APP_OPS);
}
return IExternalVibratorService.SCALE_MUTE;
}
@@ -1933,10 +1390,13 @@ public class VibratorService extends IVibratorService.Stub
if (mCurrentExternalVibration == null) {
// If we're not under external control right now, then cancel any normal
// vibration that may be playing and ready the vibrator for external control.
- doCancelVibrateLocked(VibrationInfo.Status.CANCELLED);
- setVibratorUnderExternalControl(true);
+ if (DEBUG) {
+ Slog.d(TAG, "Vibrator going under external control.");
+ }
+ doCancelVibrateLocked(Vibration.Status.CANCELLED);
+ mVibratorController.setExternalControl(true);
} else {
- endVibrationLocked(mCurrentExternalVibration, VibrationInfo.Status.CANCELLED);
+ endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED);
}
// At this point we either have an externally controlled vibration playing, or
// no vibration playing. Since the interface defines that only one externally
@@ -1966,12 +1426,12 @@ public class VibratorService extends IVibratorService.Stub
if (DEBUG) {
Slog.e(TAG, "Stopping external vibration" + vib);
}
- doCancelExternalVibrateLocked(VibrationInfo.Status.FINISHED);
+ doCancelExternalVibrateLocked(Vibration.Status.FINISHED);
}
}
}
- private void doCancelExternalVibrateLocked(VibrationInfo.Status status) {
+ private void doCancelExternalVibrateLocked(Vibration.Status status) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelExternalVibrateLocked");
try {
if (mCurrentExternalVibration == null) {
@@ -1982,7 +1442,7 @@ public class VibratorService extends IVibratorService.Stub
mCurrentExternalDeathRecipient);
mCurrentExternalDeathRecipient = null;
mCurrentExternalVibration = null;
- setVibratorUnderExternalControl(false);
+ mVibratorController.setExternalControl(false);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
@@ -1995,7 +1455,7 @@ public class VibratorService extends IVibratorService.Stub
if (DEBUG) {
Slog.d(TAG, "External vibration finished because binder died");
}
- doCancelExternalVibrateLocked(VibrationInfo.Status.CANCELLED);
+ doCancelExternalVibrateLocked(Vibration.Status.CANCELLED);
}
}
}
@@ -2180,19 +1640,19 @@ public class VibratorService extends IVibratorService.Stub
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runCapabilities");
try (PrintWriter pw = getOutPrintWriter();) {
pw.println("Vibrator capabilities:");
- if (hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
+ if (mVibratorController.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
pw.println(" Always on effects");
}
- if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
+ if (mVibratorController.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
pw.println(" Compose effects");
}
- if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
+ if (mVibratorController.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
pw.println(" Amplitude control");
}
- if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
+ if (mVibratorController.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
pw.println(" External control");
}
- if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) {
+ if (mVibratorController.hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) {
pw.println(" External amplitude control");
}
pw.println("");
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index a9f62d91592d..3270dd55218c 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -132,6 +132,16 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// TODO: make this private with a getter.
public NetworkCapabilities networkCapabilities;
public final NetworkAgentConfig networkAgentConfig;
+
+ // Underlying networks declared by the agent. Only set if supportsUnderlyingNetworks is true.
+ // The networks in this list might be declared by a VPN app using setUnderlyingNetworks and are
+ // not guaranteed to be current or correct, or even to exist.
+ public @Nullable Network[] declaredUnderlyingNetworks;
+
+ // Whether this network is always metered even if its underlying networks are unmetered.
+ // Only relevant if #supportsUnderlyingNetworks is true.
+ public boolean declaredMetered;
+
// Indicates if netd has been told to create this Network. From this point on the appropriate
// routing rules are setup and routes are added so packets can begin flowing over the Network.
// This is a sticky bit; once set it is never cleared.
@@ -474,10 +484,16 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
networkCapabilities);
}
+ /** Whether this network is a VPN. */
public boolean isVPN() {
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
}
+ /** Whether this network might have underlying networks. Currently only true for VPNs. */
+ public boolean supportsUnderlyingNetworks() {
+ return isVPN();
+ }
+
private int getCurrentScore(boolean pretendValidated) {
// TODO: We may want to refactor this into a NetworkScore class that takes a base score from
// the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index bdd315de32b1..234dcc9d74a5 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -112,7 +112,6 @@ import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnInfo;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.ArrayUtils;
-import com.android.server.ConnectivityService;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.net.BaseNetworkObserver;
@@ -123,7 +122,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -153,36 +151,13 @@ import java.util.concurrent.atomic.AtomicInteger;
public class Vpn {
private static final String NETWORKTYPE = "VPN";
private static final String TAG = "Vpn";
+ private static final String VPN_PROVIDER_NAME_BASE = "VpnNetworkProvider:";
private static final boolean LOGD = true;
// Length of time (in milliseconds) that an app hosting an always-on VPN is placed on
// the device idle allowlist during service launch and VPN bootstrap.
private static final long VPN_LAUNCH_IDLE_ALLOWLIST_DURATION_MS = 60 * 1000;
- // Settings for how much of the address space should be routed so that Vpn considers
- // "most" of the address space is routed. This is used to determine whether this Vpn
- // should be marked with the INTERNET capability.
- private static final long MOST_IPV4_ADDRESSES_COUNT;
- private static final BigInteger MOST_IPV6_ADDRESSES_COUNT;
- static {
- // 85% of the address space must be routed for Vpn to consider this VPN to provide
- // INTERNET access.
- final int howManyPercentIsMost = 85;
-
- final long twoPower32 = 1L << 32;
- MOST_IPV4_ADDRESSES_COUNT = twoPower32 * howManyPercentIsMost / 100;
- final BigInteger twoPower128 = BigInteger.ONE.shiftLeft(128);
- MOST_IPV6_ADDRESSES_COUNT = twoPower128
- .multiply(BigInteger.valueOf(howManyPercentIsMost))
- .divide(BigInteger.valueOf(100));
- }
- // How many routes to evaluate before bailing and declaring this Vpn should provide
- // the INTERNET capability. This is necessary because computing the address space is
- // O(n²) and this is running in the system service, so a limit is needed to alleviate
- // the risk of attack.
- // This is taken as a total of IPv4 + IPV6 routes for simplicity, but the algorithm
- // is actually O(n²)+O(n²).
- private static final int MAX_ROUTES_TO_EVALUATE = 150;
private static final String LOCKDOWN_ALLOWLIST_SETTING_NAME =
Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST;
/**
@@ -199,6 +174,7 @@ public class Vpn {
// automated reconnection
private final Context mContext;
+ private final ConnectivityManager mConnectivityManager;
// The context is for specific user which is created from mUserId
private final Context mUserIdContext;
@VisibleForTesting final Dependencies mDeps;
@@ -219,6 +195,7 @@ public class Vpn {
private final INetworkManagementService mNetd;
@VisibleForTesting
protected VpnConfig mConfig;
+ private final NetworkProvider mNetworkProvider;
@VisibleForTesting
protected NetworkAgent mNetworkAgent;
private final Looper mLooper;
@@ -402,6 +379,7 @@ public class Vpn {
int userId, @NonNull KeyStore keyStore, SystemServices systemServices,
Ikev2SessionCreator ikev2SessionCreator) {
mContext = context;
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
mDeps = deps;
mNetd = netService;
@@ -420,13 +398,16 @@ public class Vpn {
Log.wtf(TAG, "Problem registering observer", e);
}
+ mNetworkProvider = new NetworkProvider(context, looper, VPN_PROVIDER_NAME_BASE + mUserId);
+ // This constructor is called in onUserStart and registers the provider. The provider
+ // will be unregistered in onUserStop.
+ mConnectivityManager.registerNetworkProvider(mNetworkProvider);
mLegacyState = LegacyVpnInfo.STATE_DISCONNECTED;
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_VPN, 0 /* subtype */, NETWORKTYPE,
"" /* subtypeName */);
mNetworkCapabilities = new NetworkCapabilities();
mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
- updateCapabilities(null /* defaultNetwork */);
loadAlwaysOnPackage(keyStore);
}
@@ -444,12 +425,39 @@ public class Vpn {
* Update current state, dispatching event to listeners.
*/
@VisibleForTesting
+ @GuardedBy("this")
protected void updateState(DetailedState detailedState, String reason) {
if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason);
mLegacyState = LegacyVpnInfo.stateFromNetworkInfo(detailedState);
mNetworkInfo.setDetailedState(detailedState, reason, null);
- if (mNetworkAgent != null) {
- mNetworkAgent.sendNetworkInfo(mNetworkInfo);
+ // TODO : only accept transitions when the agent is in the correct state (non-null for
+ // CONNECTED, DISCONNECTED and FAILED, null for CONNECTED).
+ // This will require a way for tests to pretend the VPN is connected that's not
+ // calling this method with CONNECTED.
+ // It will also require audit of where the code calls this method with DISCONNECTED
+ // with a null agent, which it was doing historically to make sure the agent is
+ // disconnected as this was a no-op if the agent was null.
+ switch (detailedState) {
+ case CONNECTED:
+ if (null != mNetworkAgent) {
+ mNetworkAgent.markConnected();
+ }
+ break;
+ case DISCONNECTED:
+ case FAILED:
+ if (null != mNetworkAgent) {
+ mNetworkAgent.unregister();
+ mNetworkAgent = null;
+ }
+ break;
+ case CONNECTING:
+ if (null != mNetworkAgent) {
+ throw new IllegalStateException("VPN can only go to CONNECTING state when"
+ + " the agent is null.");
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Illegal state argument " + detailedState);
}
updateAlwaysOnNotification(detailedState);
}
@@ -477,7 +485,7 @@ public class Vpn {
final boolean isAlwaysMetered = mIsPackageTargetingAtLeastQ && mConfig.isMetered;
applyUnderlyingCapabilities(
- mContext.getSystemService(ConnectivityManager.class),
+ mConnectivityManager,
underlyingNetworks,
mNetworkCapabilities,
isAlwaysMetered);
@@ -487,10 +495,10 @@ public class Vpn {
@VisibleForTesting
public static void applyUnderlyingCapabilities(
- ConnectivityManager cm,
- Network[] underlyingNetworks,
- NetworkCapabilities caps,
- boolean isAlwaysMetered) {
+ @NonNull final ConnectivityManager cm,
+ @Nullable final Network[] underlyingNetworks,
+ @NonNull final NetworkCapabilities caps,
+ final boolean isAlwaysMetered) {
int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN };
int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
@@ -1017,7 +1025,7 @@ public class Vpn {
}
mConfig = null;
- updateState(DetailedState.IDLE, "prepare");
+ updateState(DetailedState.DISCONNECTED, "prepare");
setVpnForcedLocked(mLockdown);
} finally {
Binder.restoreCallingIdentity(token);
@@ -1253,7 +1261,7 @@ public class Vpn {
mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
mLegacyState = LegacyVpnInfo.STATE_CONNECTING;
- mNetworkInfo.setDetailedState(DetailedState.CONNECTING, null, null);
+ updateState(DetailedState.CONNECTING, "agentConnect");
NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
@@ -1262,20 +1270,34 @@ public class Vpn {
mNetworkCapabilities.setAdministratorUids(new int[] {mOwnerUID});
mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserId,
mConfig.allowedApplications, mConfig.disallowedApplications));
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE /* logtag */,
- mNetworkInfo, mNetworkCapabilities, lp,
- ConnectivityConstants.VPN_DEFAULT_SCORE, networkAgentConfig,
- NetworkProvider.ID_VPN) {
- @Override
- public void unwanted() {
- // We are user controlled, not driven by NetworkRequest.
- }
- };
- } finally {
- Binder.restoreCallingIdentity(token);
+
+ // Only apps targeting Q and above can explicitly declare themselves as metered.
+ // These VPNs are assumed metered unless they state otherwise.
+ if (mIsPackageTargetingAtLeastQ && mConfig.isMetered) {
+ mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_METERED);
+ } else {
+ mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
}
+
+ mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
+ mNetworkCapabilities, lp,
+ ConnectivityConstants.VPN_DEFAULT_SCORE, networkAgentConfig, mNetworkProvider) {
+ @Override
+ public void unwanted() {
+ // We are user controlled, not driven by NetworkRequest.
+ }
+ };
+ Binder.withCleanCallingIdentity(() -> {
+ try {
+ mNetworkAgent.register();
+ } catch (final Exception e) {
+ // If register() throws, don't keep an unregistered agent.
+ mNetworkAgent = null;
+ throw e;
+ }
+ });
+ mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
+ ? Arrays.asList(mConfig.underlyingNetworks) : null);
mNetworkInfo.setIsAvailable(true);
updateState(DetailedState.CONNECTED, "agentConnect");
}
@@ -1291,19 +1313,12 @@ public class Vpn {
private void agentDisconnect(NetworkAgent networkAgent) {
if (networkAgent != null) {
- NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
- networkInfo.setIsAvailable(false);
- networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
- networkAgent.sendNetworkInfo(networkInfo);
+ networkAgent.unregister();
}
}
private void agentDisconnect() {
- if (mNetworkInfo.isConnected()) {
- mNetworkInfo.setIsAvailable(false);
- updateState(DetailedState.DISCONNECTED, "agentDisconnect");
- mNetworkAgent = null;
- }
+ updateState(DetailedState.DISCONNECTED, "agentDisconnect");
}
/**
@@ -1392,6 +1407,8 @@ public class Vpn {
&& updateLinkPropertiesInPlaceIfPossible(mNetworkAgent, oldConfig)) {
// Keep mNetworkAgent unchanged
} else {
+ // Initialize the state for a new agent, while keeping the old one connected
+ // in case this new connection fails.
mNetworkAgent = null;
updateState(DetailedState.CONNECTING, "establish");
// Set up forwarding and DNS rules.
@@ -1575,12 +1592,13 @@ public class Vpn {
try {
addUserToRanges(existingRanges, userId, mConfig.allowedApplications,
mConfig.disallowedApplications);
- // ConnectivityService will call {@link #updateCapabilities} and apply
- // those for VPN network.
mNetworkCapabilities.setUids(existingRanges);
} catch (Exception e) {
Log.wtf(TAG, "Failed to add restricted user to owner", e);
}
+ if (mNetworkAgent != null) {
+ mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
+ }
}
setVpnForcedLocked(mLockdown);
}
@@ -1603,12 +1621,13 @@ public class Vpn {
final List<UidRange> removedRanges =
uidRangesForUser(userId, existingRanges);
existingRanges.removeAll(removedRanges);
- // ConnectivityService will call {@link #updateCapabilities} and
- // apply those for VPN network.
mNetworkCapabilities.setUids(existingRanges);
} catch (Exception e) {
Log.wtf(TAG, "Failed to remove restricted user to owner", e);
}
+ if (mNetworkAgent != null) {
+ mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
+ }
}
setVpnForcedLocked(mLockdown);
}
@@ -1625,6 +1644,9 @@ public class Vpn {
// Quit any active connections
agentDisconnect();
+
+ // The provider has been registered in the constructor, which is called in onUserStart.
+ mConnectivityManager.unregisterNetworkProvider(mNetworkProvider);
}
/**
@@ -1857,6 +1879,8 @@ public class Vpn {
}
}
}
+ mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
+ ? Arrays.asList(mConfig.underlyingNetworks) : null);
return true;
}
@@ -2399,7 +2423,6 @@ public class Vpn {
// When restricted to test networks, select any network with TRANSPORT_TEST. Since the
// creator of the profile and the test network creator both have MANAGE_TEST_NETWORKS,
// this is considered safe.
- final ConnectivityManager cm = ConnectivityManager.from(mContext);
final NetworkRequest req;
if (mProfile.isRestrictedToTestNetworks()) {
@@ -2418,7 +2441,7 @@ public class Vpn {
.build();
}
- cm.requestNetwork(req, mNetworkCallback);
+ mConnectivityManager.requestNetwork(req, mNetworkCallback);
}
private boolean isActiveNetwork(@Nullable Network network) {
@@ -2705,8 +2728,7 @@ public class Vpn {
resetIkeState();
- final ConnectivityManager cm = ConnectivityManager.from(mContext);
- cm.unregisterNetworkCallback(mNetworkCallback);
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
mExecutor.shutdown();
}
@@ -2787,13 +2809,12 @@ public class Vpn {
mProfile = profile;
if (!TextUtils.isEmpty(mOuterInterface)) {
- final ConnectivityManager cm = ConnectivityManager.from(mContext);
- for (Network network : cm.getAllNetworks()) {
- final LinkProperties lp = cm.getLinkProperties(network);
+ for (Network network : mConnectivityManager.getAllNetworks()) {
+ final LinkProperties lp = mConnectivityManager.getLinkProperties(network);
if (lp != null && lp.getAllInterfaceNames().contains(mOuterInterface)) {
- final NetworkInfo networkInfo = cm.getNetworkInfo(network);
- if (networkInfo != null) {
- mOuterConnection.set(networkInfo.getType());
+ final NetworkInfo netInfo = mConnectivityManager.getNetworkInfo(network);
+ if (netInfo != null) {
+ mOuterConnection.set(netInfo.getType());
break;
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index 0566d32160fc..2374ece1dd65 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -22,12 +22,19 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
+import android.database.ContentObserver;
import android.hardware.hdmi.HdmiControlManager;
+import android.net.Uri;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.provider.Settings.Global;
+import android.util.ArrayMap;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -85,9 +92,26 @@ public class HdmiCecConfig {
@NonNull private final Context mContext;
@NonNull private final StorageAdapter mStorageAdapter;
- @Nullable private final CecSettings mSystemConfig;
+ @Nullable private final CecSettings mProductConfig;
@Nullable private final CecSettings mVendorOverride;
+ private final ArrayMap<Setting, Set<SettingChangeListener>>
+ mSettingChangeListeners = new ArrayMap<>();
+
+ private SettingsObserver mSettingsObserver;
+
+ /**
+ * Listener used to get notifications when value of a setting changes.
+ */
+ public interface SettingChangeListener {
+ /**
+ * Called when value of a setting changes.
+ *
+ * @param setting name of a CEC setting that changed
+ */
+ void onChange(@NonNull @CecSettingName String setting);
+ }
+
/**
* Setting storage input/output helper class.
*/
@@ -159,17 +183,29 @@ public class HdmiCecConfig {
}
}
+ private class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ String setting = uri.getLastPathSegment();
+ HdmiCecConfig.this.notifyGlobalSettingChanged(setting);
+ }
+ }
+
@VisibleForTesting
HdmiCecConfig(@NonNull Context context,
@NonNull StorageAdapter storageAdapter,
- @Nullable CecSettings systemConfig,
+ @Nullable CecSettings productConfig,
@Nullable CecSettings vendorOverride) {
mContext = context;
mStorageAdapter = storageAdapter;
- mSystemConfig = systemConfig;
+ mProductConfig = productConfig;
mVendorOverride = vendorOverride;
- if (mSystemConfig == null) {
- Slog.i(TAG, "CEC system configuration XML missing.");
+ if (mProductConfig == null) {
+ Slog.i(TAG, "CEC master configuration XML missing.");
}
if (mVendorOverride == null) {
Slog.i(TAG, "CEC OEM configuration override XML missing.");
@@ -178,7 +214,7 @@ public class HdmiCecConfig {
HdmiCecConfig(@NonNull Context context) {
this(context, new StorageAdapter(context),
- readSettingsFromFile(Environment.buildPath(Environment.getRootDirectory(),
+ readSettingsFromFile(Environment.buildPath(Environment.getProductDirectory(),
ETC_DIR, CONFIG_FILE)),
readSettingsFromFile(Environment.buildPath(Environment.getVendorDirectory(),
ETC_DIR, CONFIG_FILE)));
@@ -205,14 +241,14 @@ public class HdmiCecConfig {
@VisibleForTesting
static HdmiCecConfig createFromStrings(@NonNull Context context,
@NonNull StorageAdapter storageAdapter,
- @Nullable String systemConfigXml,
+ @Nullable String productConfigXml,
@Nullable String vendorOverrideXml) {
- CecSettings systemConfig = null;
+ CecSettings productConfig = null;
CecSettings vendorOverride = null;
try {
- if (systemConfigXml != null) {
- systemConfig = XmlParser.read(
- new ByteArrayInputStream(systemConfigXml.getBytes()));
+ if (productConfigXml != null) {
+ productConfig = XmlParser.read(
+ new ByteArrayInputStream(productConfigXml.getBytes()));
}
if (vendorOverrideXml != null) {
vendorOverride = XmlParser.read(
@@ -221,12 +257,12 @@ public class HdmiCecConfig {
} catch (IOException | DatatypeConfigurationException | XmlPullParserException e) {
Slog.e(TAG, "Encountered an error while reading/parsing CEC config strings", e);
}
- return new HdmiCecConfig(context, storageAdapter, systemConfig, vendorOverride);
+ return new HdmiCecConfig(context, storageAdapter, productConfig, vendorOverride);
}
@Nullable
private Setting getSetting(@NonNull String name) {
- if (mSystemConfig == null) {
+ if (mProductConfig == null) {
return null;
}
if (mVendorOverride != null) {
@@ -237,8 +273,8 @@ public class HdmiCecConfig {
}
}
}
- // If not found, try the system config.
- for (Setting setting : mSystemConfig.getSetting()) {
+ // If not found, try the product config.
+ for (Setting setting : mProductConfig.getSetting()) {
if (setting.getName().equals(name)) {
return setting;
}
@@ -311,6 +347,7 @@ public class HdmiCecConfig {
} else if (storage == STORAGE_SHARED_PREFS) {
Slog.d(TAG, "Setting '" + storageKey + "' shared pref.");
mStorageAdapter.storeSharedPref(storageKey, value);
+ notifySettingChanged(setting);
}
}
@@ -318,15 +355,112 @@ public class HdmiCecConfig {
return Integer.decode(value.getIntValue());
}
+ private void notifyGlobalSettingChanged(String setting) {
+ switch (setting) {
+ case Global.HDMI_CONTROL_ENABLED:
+ notifySettingChanged(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED);
+ break;
+ case Global.HDMI_CEC_VERSION:
+ notifySettingChanged(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION);
+ break;
+ case Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP:
+ notifySettingChanged(HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
+ break;
+ }
+ }
+
+ private void notifySettingChanged(@NonNull @CecSettingName String name) {
+ Setting setting = getSetting(name);
+ if (setting == null) {
+ throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+ }
+ notifySettingChanged(setting);
+ }
+
+ private void notifySettingChanged(@NonNull Setting setting) {
+ Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
+ if (listeners == null) {
+ return; // No listeners registered, do nothing.
+ }
+ for (SettingChangeListener listener: listeners) {
+ listener.onChange(setting.getName());
+ }
+ }
+
+ /**
+ * This method registers Global Setting change observer.
+ * Needs to be called once after initialization of HdmiCecConfig.
+ */
+ public void registerGlobalSettingsObserver(Looper looper) {
+ Handler handler = new Handler(looper);
+ mSettingsObserver = new SettingsObserver(handler);
+ ContentResolver resolver = mContext.getContentResolver();
+ String[] settings = new String[] {
+ Global.HDMI_CONTROL_ENABLED,
+ Global.HDMI_CEC_VERSION,
+ Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
+ };
+ for (String setting: settings) {
+ resolver.registerContentObserver(Global.getUriFor(setting), false,
+ mSettingsObserver, UserHandle.USER_ALL);
+ }
+ }
+
+ /**
+ * This method unregisters Global Setting change observer.
+ */
+ public void unregisterGlobalSettingsObserver() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.unregisterContentObserver(mSettingsObserver);
+ }
+
+ /**
+ * Register change listener for a given setting name.
+ */
+ public void registerChangeListener(@NonNull @CecSettingName String name,
+ SettingChangeListener listener) {
+ Setting setting = getSetting(name);
+ if (setting == null) {
+ throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+ }
+ @Storage int storage = getStorage(setting);
+ if (storage != STORAGE_GLOBAL_SETTINGS && storage != STORAGE_SHARED_PREFS) {
+ throw new IllegalArgumentException("Change listeners for setting '" + name
+ + "' not supported.");
+ }
+ if (!mSettingChangeListeners.containsKey(setting)) {
+ mSettingChangeListeners.put(setting, new HashSet<>());
+ }
+ mSettingChangeListeners.get(setting).add(listener);
+ }
+
+ /**
+ * Remove change listener for a given setting name.
+ */
+ public void removeChangeListener(@NonNull @CecSettingName String name,
+ SettingChangeListener listener) {
+ Setting setting = getSetting(name);
+ if (setting == null) {
+ throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+ }
+ if (mSettingChangeListeners.containsKey(setting)) {
+ Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
+ listeners.remove(listener);
+ if (listeners.isEmpty()) {
+ mSettingChangeListeners.remove(setting);
+ }
+ }
+ }
+
/**
* Returns a list of all settings based on the XML metadata.
*/
public @CecSettingName List<String> getAllSettings() {
- if (mSystemConfig == null) {
+ if (mProductConfig == null) {
return new ArrayList<String>();
}
List<String> allSettings = new ArrayList<String>();
- for (Setting setting : mSystemConfig.getSetting()) {
+ for (Setting setting : mProductConfig.getSetting()) {
allSettings.add(setting.getName());
}
return allSettings;
@@ -336,12 +470,12 @@ public class HdmiCecConfig {
* Returns a list of user-modifiable settings based on the XML metadata.
*/
public @CecSettingName List<String> getUserSettings() {
- if (mSystemConfig == null) {
+ if (mProductConfig == null) {
return new ArrayList<String>();
}
Set<String> userSettings = new HashSet<String>();
- // First read from the system config.
- for (Setting setting : mSystemConfig.getSetting()) {
+ // First read from the product config.
+ for (Setting setting : mProductConfig.getSetting()) {
if (setting.getUserConfigurable()) {
userSettings.add(setting.getName());
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 1cbbe2dc5b6a..9b3f788d7457 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -566,6 +566,11 @@ abstract class HdmiCecLocalDevice {
return false;
}
+ reportFeatures();
+ return true;
+ }
+
+ protected void reportFeatures() {
List<Integer> localDeviceTypes = new ArrayList<>();
for (HdmiCecLocalDevice localDevice : mService.getAllLocalDevices()) {
localDeviceTypes.add(localDevice.mDeviceType);
@@ -579,7 +584,6 @@ abstract class HdmiCecLocalDevice {
mService.sendCecCommand(
HdmiCecMessageBuilder.buildReportFeatures(mAddress, mService.getCecVersion(),
localDeviceTypes, rcProfile, rcFeatures, deviceFeatures));
- return true;
}
@ServiceThreadOnly
@@ -791,6 +795,9 @@ abstract class HdmiCecLocalDevice {
final void handleAddressAllocated(int logicalAddress, int reason) {
assertRunOnServiceThread();
mAddress = mPreferredAddress = logicalAddress;
+ if (mService.getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0) {
+ reportFeatures();
+ }
onAddressAllocated(logicalAddress, reason);
setPreferredAddress(logicalAddress);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 01ec3b4cd823..fd825d6f6288 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -563,6 +563,7 @@ public class HdmiControlService extends SystemService {
if (mMessageValidator == null) {
mMessageValidator = new HdmiCecMessageValidator(this);
}
+ mHdmiCecConfig.registerGlobalSettingsObserver(mIoLooper);
}
private void bootCompleted() {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index cfb5116c47f3..0ceaf7748eba 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -15,6 +15,7 @@
package com.android.server.inputmethod;
+import static android.inputmethodservice.InputMethodService.FINISH_INPUT_NO_FALLBACK_CONNECTION;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -45,6 +46,8 @@ import static android.server.inputmethod.InputMethodManagerServiceProto.SYSTEM_R
import static android.util.imetracing.ImeTracing.IME_TRACING_FROM_IMMS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_HIDE;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -118,7 +121,6 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.IndentingPrintWriter;
-import android.util.Log;
import android.util.LruCache;
import android.util.Pair;
import android.util.PrintWriterPrinter;
@@ -131,6 +133,8 @@ import android.view.DisplayInfo;
import android.view.IWindowManager;
import android.view.InputChannel;
import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.autofill.AutofillId;
@@ -152,6 +156,7 @@ import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.compat.IPlatformCompat;
import com.android.internal.content.PackageMonitor;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
@@ -531,6 +536,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int mCurSeq;
/**
+ * {@code true} if the Ime policy has been set to {@link WindowManager#DISPLAY_IME_POLICY_HIDE}.
+ *
+ * This prevents the IME from showing when it otherwise may have shown.
+ */
+ boolean mImeHiddenByDisplayPolicy;
+
+ /**
* The client that is currently bound to an input method.
*/
ClientState mCurClient;
@@ -709,6 +721,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
boolean mIsInteractive = true;
+ private IPlatformCompat mPlatformCompat;
+
int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
/**
@@ -1658,7 +1672,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
- mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId);
+ mImeDisplayValidator = displayId -> mWindowManagerInternal.getDisplayImePolicy(displayId);
mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@Override
public void executeMessage(Message msg) {
@@ -1670,6 +1684,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mHasFeature = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_INPUT_METHODS);
+ mPlatformCompat = IPlatformCompat.Stub.asInterface(
+ ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime);
mIsLowRam = ActivityManager.isLowRamDeviceStatic();
@@ -2306,8 +2322,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
- MSG_SET_ACTIVE, 0, 0, mCurClient));
+ scheduleSetActiveToClient(mCurClient, false /* active */, false /* fullscreen */,
+ false /* reportToImeController */);
executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
MSG_UNBIND_CLIENT, mCurSeq, unbindClientReason, mCurClient.client));
mCurClient.sessionRequested = false;
@@ -2438,6 +2454,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final int displayIdToShowIme = computeImeDisplayIdForTarget(cs.selfReportedDisplayId,
mImeDisplayValidator);
+ if (displayIdToShowIme == INVALID_DISPLAY) {
+ mImeHiddenByDisplayPolicy = true;
+ return InputBindResult.NO_IME;
+ }
+ mImeHiddenByDisplayPolicy = false;
+
if (mCurClient != cs) {
// Was the keyguard locked when switching over to the new client?
mCurClientInKeyguard = isKeyguardLocked();
@@ -2449,7 +2471,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// If the screen is on, inform the new client it is active
if (mIsInteractive) {
- executeOrSendMessage(cs.client, mCaller.obtainMessageIO(MSG_SET_ACTIVE, 1, cs));
+ scheduleSetActiveToClient(cs, true /* active */, false /* fullscreen */,
+ false /* reportToImeController */);
}
}
@@ -2549,7 +2572,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@FunctionalInterface
interface ImeDisplayValidator {
- boolean displayCanShowIme(int displayId);
+ @DisplayImePolicy int getDisplayImePolicy(int displayId);
}
/**
@@ -2558,7 +2581,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* @param displayId the ID of the display where the IME client target is.
* @param checker instance of {@link ImeDisplayValidator} which is used for
* checking display config to adjust the final target display.
- * @return The ID of the display where the IME should be shown.
+ * @return The ID of the display where the IME should be shown or
+ * {@link android.view.Display#INVALID_DISPLAY} if the display has an ImePolicy of
+ * {@link WindowManager#DISPLAY_IME_POLICY_HIDE}.
*/
static int computeImeDisplayIdForTarget(int displayId, @NonNull ImeDisplayValidator checker) {
if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY) {
@@ -2567,7 +2592,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Show IME window on fallback display when the display doesn't support system decorations
// or the display is virtual and isn't owned by system for security concern.
- return checker.displayCanShowIme(displayId) ? displayId : FALLBACK_DISPLAY_ID;
+ final int result = checker.getDisplayImePolicy(displayId);
+ if (result == DISPLAY_IME_POLICY_LOCAL) {
+ return displayId;
+ } else if (result == DISPLAY_IME_POLICY_HIDE) {
+ return INVALID_DISPLAY;
+ } else {
+ return FALLBACK_DISPLAY_ID;
+ }
}
@AnyThread
@@ -4077,6 +4109,44 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return ImeTracing.getInstance().isEnabled();
}
+ @BinderThread
+ @Override
+ public void startImeTrace() {
+ ImeTracing.getInstance().startTrace(null /* printwriter */);
+ ArrayMap<IBinder, ClientState> clients;
+ synchronized (mMethodMap) {
+ clients = new ArrayMap<>(mClients);
+ }
+ for (ClientState state : clients.values()) {
+ if (state != null) {
+ try {
+ state.client.setImeTraceEnabled(true /* enabled */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error while trying to enable ime trace on client window", e);
+ }
+ }
+ }
+ }
+
+ @BinderThread
+ @Override
+ public void stopImeTrace() {
+ ImeTracing.getInstance().stopTrace(null /* printwriter */);
+ ArrayMap<IBinder, ClientState> clients;
+ synchronized (mMethodMap) {
+ clients = new ArrayMap<>(mClients);
+ }
+ for (ClientState state : clients.values()) {
+ if (state != null) {
+ try {
+ state.client.setImeTraceEnabled(false /* enabled */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error while trying to disable ime trace on client window", e);
+ }
+ }
+ }
+ }
+
@GuardedBy("mMethodMap")
private void dumpDebug(ProtoOutputStream proto, long fieldId) {
synchronized (mMethodMap) {
@@ -4452,15 +4522,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
args.recycle();
return true;
}
- case MSG_SET_ACTIVE:
+ case MSG_SET_ACTIVE: {
+ args = (SomeArgs) msg.obj;
+ final ClientState clientState = (ClientState) args.arg1;
try {
- ((ClientState)msg.obj).client.setActive(msg.arg1 != 0, msg.arg2 != 0);
+ clientState.client.setActive(args.argi1 != 0 /* active */,
+ args.argi2 != 0 /* fullScreen */,
+ args.argi3 != 0 /* reportToImeController */);
} catch (RemoteException e) {
Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid "
- + ((ClientState)msg.obj).pid + " uid "
- + ((ClientState)msg.obj).uid);
+ + clientState.pid + " uid " + clientState.uid);
}
+ args.recycle();
return true;
+ }
case MSG_SET_INTERACTIVE:
handleSetInteractive(msg.arg1 != 0);
return true;
@@ -4546,13 +4621,24 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Inform the current client of the change in active status
if (mCurClient != null && mCurClient.client != null) {
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
- MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, mInFullscreenMode ? 1 : 0,
- mCurClient));
+ boolean reportToImeController = false;
+ try {
+ reportToImeController = mPlatformCompat.isChangeEnabledByUid(
+ FINISH_INPUT_NO_FALLBACK_CONNECTION, mCurMethodUid);
+ } catch (RemoteException e) {
+ }
+ scheduleSetActiveToClient(mCurClient, mIsInteractive, mInFullscreenMode,
+ reportToImeController);
}
}
}
+ private void scheduleSetActiveToClient(ClientState state, boolean active, boolean fullscreen,
+ boolean reportToImeController) {
+ executeOrSendMessage(state.client, mCaller.obtainMessageIIIIO(MSG_SET_ACTIVE,
+ active ? 1 : 0, fullscreen ? 1 : 0, reportToImeController ? 1 : 0, 0, state));
+ }
+
private boolean chooseNewDefaultIMELocked() {
final InputMethodInfo imi = InputMethodUtils.getMostApplicableDefaultIME(
mSettings.getEnabledInputMethodListLocked());
@@ -5181,6 +5267,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
p.println(" mInFullscreenMode=" + mInFullscreenMode);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
p.println(" mSettingsObserver=" + mSettingsObserver);
+ p.println(" mImeHiddenByDisplayPolicy=" + mImeHiddenByDisplayPolicy);
p.println(" mSwitchingController:");
mSwitchingController.dump(p);
p.println(" mSettings:");
@@ -5722,9 +5809,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
try {
state.client.setImeTraceEnabled(isImeTraceEnabled);
} catch (RemoteException e) {
- Log.e(TAG,
- "Error while trying to enable/disable ime "
- + "trace on client window", e);
+ Slog.e(TAG, "Error while trying to enable/disable ime trace on client window",
+ e);
}
}
}
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 7af27ca46f68..62d817c22ae6 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -911,7 +911,8 @@ public final class MultiClientInputMethodManagerService {
com.android.internal.R.string.input_method_binding_label)
.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
context, 0,
- new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
+ new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS),
+ PendingIntent.FLAG_MUTABLE));
// Note: Instead of re-dispatching callback from the main thread to the worker thread
// where OnWorkerThreadCallback is running, we pass the Handler object here so that
@@ -1338,7 +1339,7 @@ public final class MultiClientInputMethodManagerService {
switch (clientInfo.mState) {
case InputMethodClientState.WAITING_FOR_IME_SESSION:
try {
- clientInfo.mClient.setActive(true, false);
+ clientInfo.mClient.setActive(true, false, false);
} catch (RemoteException e) {
// TODO(yukawa): Remove this client.
return;
@@ -1400,7 +1401,7 @@ public final class MultiClientInputMethodManagerService {
return;
}
try {
- clientInfo.mClient.setActive(active, false /* fullscreen */);
+ clientInfo.mClient.setActive(active, false /* fullscreen */, false);
} catch (RemoteException e) {
return;
}
@@ -1816,5 +1817,15 @@ public final class MultiClientInputMethodManagerService {
public boolean isImeTraceEnabled() {
return false;
}
+
+ @BinderThread
+ @Override
+ public void startImeTrace() {
+ }
+
+ @BinderThread
+ @Override
+ public void stopImeTrace() {
+ }
}
}
diff --git a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
index 9d262e33274b..77253099d54f 100644
--- a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
+++ b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
@@ -117,7 +117,7 @@ final class SimulatedBinderProviderEvent {
private static LocationTimeZoneEvent parseLocationTimeZoneEventArgs(ShellCommand shellCommand) {
LocationTimeZoneEvent.Builder eventBuilder = new LocationTimeZoneEvent.Builder()
- .setElapsedRealtimeNanos(SystemClock.elapsedRealtime());
+ .setElapsedRealtimeMillis(SystemClock.elapsedRealtime());
String eventTypeString = shellCommand.getNextArgRequired();
switch (eventTypeString.toUpperCase()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 55f9feec10d3..db5eb844f1b4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5717,7 +5717,8 @@ public class PackageManagerService extends IPackageManager.Stub
getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
(libInfo.getDependencies() == null
? null
- : new ArrayList<>(libInfo.getDependencies())));
+ : new ArrayList<>(libInfo.getDependencies())),
+ libInfo.isNative());
if (result == null) {
result = new ArrayList<>();
@@ -5786,7 +5787,8 @@ public class PackageManagerService extends IPackageManager.Stub
libraryInfo.getLongVersion(), libraryInfo.getType(),
libraryInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(
libraryInfo, flags, userId), libraryInfo.getDependencies() == null
- ? null : new ArrayList<>(libraryInfo.getDependencies()));
+ ? null : new ArrayList<>(libraryInfo.getDependencies()),
+ libraryInfo.isNative());
if (result == null) {
result = new ArrayList<>();
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
index 0a56e1343418..ab25a7c772c0 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
@@ -94,7 +94,7 @@ public class AndroidPackageUtils {
SharedLibraryInfo.TYPE_STATIC,
new VersionedPackage(pkg.getManifestPackageName(),
pkg.getLongVersionCode()),
- null, null);
+ null, null, false /* isNative */);
}
public static SharedLibraryInfo createSharedLibraryForDynamic(AndroidPackage pkg, String name) {
@@ -103,7 +103,7 @@ public class AndroidPackageUtils {
SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_DYNAMIC, new VersionedPackage(pkg.getPackageName(),
pkg.getLongVersionCode()),
- null, null);
+ null, null, false /* isNative */);
}
/**
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index cc369356c1c9..9026262db897 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -127,9 +127,11 @@ public abstract class SoftRestrictedPermissionPolicy {
final boolean isWhiteListed;
boolean shouldApplyRestriction;
final int targetSDK;
+ final boolean hasLegacyExternalStorage;
final boolean hasRequestedLegacyExternalStorage;
- final boolean shouldPreserveLegacyExternalStorage;
+ final boolean hasRequestedPreserveLegacyExternalStorage;
final boolean hasWriteMediaStorageGrantedForUid;
+ final boolean isForcedScopedStorage;
if (appInfo != null) {
PackageManager pm = context.getPackageManager();
@@ -137,27 +139,27 @@ public abstract class SoftRestrictedPermissionPolicy {
LocalServices.getService(StorageManagerInternal.class);
int flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
+ hasLegacyExternalStorage = smInternal.hasLegacyExternalStorage(appInfo.uid);
hasRequestedLegacyExternalStorage = hasUidRequestedLegacyExternalStorage(
appInfo.uid, context);
hasWriteMediaStorageGrantedForUid = hasWriteMediaStorageGrantedForUid(
appInfo.uid, context);
- shouldPreserveLegacyExternalStorage = pkg.hasPreserveLegacyExternalStorage()
- && smInternal.hasLegacyExternalStorage(appInfo.uid);
+ hasRequestedPreserveLegacyExternalStorage =
+ pkg.hasPreserveLegacyExternalStorage();
targetSDK = getMinimumTargetSDK(context, appInfo, user);
- shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0
- || (targetSDK > Build.VERSION_CODES.Q
- && !shouldPreserveLegacyExternalStorage)
- // If the device is configured to force this app into scoped storage,
- // then we should apply the restriction
- || sForcedScopedStorageAppWhitelist.contains(appInfo.packageName);
+ shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+ isForcedScopedStorage = sForcedScopedStorageAppWhitelist
+ .contains(appInfo.packageName);
} else {
isWhiteListed = false;
shouldApplyRestriction = false;
targetSDK = 0;
+ hasLegacyExternalStorage = false;
hasRequestedLegacyExternalStorage = false;
- shouldPreserveLegacyExternalStorage = false;
+ hasRequestedPreserveLegacyExternalStorage = false;
hasWriteMediaStorageGrantedForUid = false;
+ isForcedScopedStorage = false;
}
// We have a check in PermissionPolicyService.PermissionToOpSynchroniser.setUidMode
@@ -175,14 +177,53 @@ public abstract class SoftRestrictedPermissionPolicy {
}
@Override
public boolean mayAllowExtraAppOp() {
- return !shouldApplyRestriction
- && (hasRequestedLegacyExternalStorage
- || hasWriteMediaStorageGrantedForUid
- || shouldPreserveLegacyExternalStorage);
+ // The only way to get LEGACY_STORAGE (if you didn't already have it)
+ // is that all of the following must be true:
+ // 1. The flag shouldn't be restricted
+ if (shouldApplyRestriction) {
+ return false;
+ }
+
+ // 2. The app shouldn't be in sForcedScopedStorageAppWhitelist
+ if (isForcedScopedStorage) {
+ return false;
+ }
+
+ // 3. The app has WRITE_MEDIA_STORAGE, OR
+ // the app already has legacy external storage or requested it,
+ // and is < R.
+ return hasWriteMediaStorageGrantedForUid
+ || ((hasLegacyExternalStorage || hasRequestedLegacyExternalStorage)
+ && targetSDK < Build.VERSION_CODES.R);
}
@Override
public boolean mayDenyExtraAppOpIfGranted() {
- return shouldApplyRestriction;
+ // If you're an app targeting < R, you can keep the app op for
+ // as long as you meet the conditions required to acquire it.
+ if (targetSDK < Build.VERSION_CODES.R) {
+ return !mayAllowExtraAppOp();
+ }
+
+ // For an app targeting R, the only way to lose LEGACY_STORAGE if you
+ // already had it is in one or more of the following conditions:
+ // 1. The flag became restricted
+ if (shouldApplyRestriction) {
+ return true;
+ }
+
+ // The package is now a part of the forced scoped storage whitelist
+ if (isForcedScopedStorage) {
+ return true;
+ }
+
+ // The package doesn't have WRITE_MEDIA_STORAGE,
+ // AND didn't request legacy storage to be preserved
+ if (!hasWriteMediaStorageGrantedForUid
+ && !hasRequestedPreserveLegacyExternalStorage) {
+ return true;
+ }
+
+ return false;
}
};
}
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 2d51cf9a5083..63ed416f2859 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -141,11 +141,17 @@ class Rollback {
/**
* The current state of the rollback.
- * ENABLING, AVAILABLE, or COMMITTED.
+ * ENABLING, AVAILABLE, DELETED, or COMMITTED.
*/
private @RollbackState int mState;
/**
+ * The detailed description of the current state. For a DELETED state, it describes
+ * the reason why the rollback is deleted.
+ */
+ private @NonNull String mStateDescription = "";
+
+ /**
* True if we are expecting the package manager to call restoreUserData
* for this rollback because it has just been committed but the rollback
* has not yet been fully applied.
@@ -231,7 +237,7 @@ class Rollback {
* Constructs a pre-populated Rollback instance.
*/
Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
- @RollbackState int state, boolean restoreUserDataInProgress,
+ @RollbackState int state, String stateDescription, boolean restoreUserDataInProgress,
int userId, String installerPackageName, SparseIntArray extensionVersions) {
this.info = info;
mUserId = userId;
@@ -240,6 +246,7 @@ class Rollback {
mTimestamp = timestamp;
mStagedSessionId = stagedSessionId;
mState = state;
+ mStateDescription = stateDescription;
mRestoreUserDataInProgress = restoreUserDataInProgress;
mExtensionVersions = Objects.requireNonNull(extensionVersions);
// TODO(b/120200473): Include this field during persistence. This field will be used to
@@ -478,7 +485,7 @@ class Rollback {
Slog.w(TAG, "Cannot make deleted rollback available.");
return;
}
- mState = ROLLBACK_STATE_AVAILABLE;
+ setState(ROLLBACK_STATE_AVAILABLE, "");
mTimestamp = Instant.now();
RollbackStore.saveRollback(this);
}
@@ -598,7 +605,7 @@ class Rollback {
// Why would we expect commit not to fail again?
// TODO: Could this cause a rollback to be resurrected
// if it should otherwise have expired by now?
- mState = ROLLBACK_STATE_AVAILABLE;
+ setState(ROLLBACK_STATE_AVAILABLE, "Commit failed");
mRestoreUserDataInProgress = false;
info.setCommittedSessionId(-1);
sendFailure(context, statusReceiver,
@@ -642,7 +649,7 @@ class Rollback {
};
final LocalIntentReceiver receiver = new LocalIntentReceiver(onResult);
- mState = ROLLBACK_STATE_COMMITTED;
+ setState(ROLLBACK_STATE_COMMITTED, "");
info.setCommittedSessionId(parentSessionId);
mRestoreUserDataInProgress = true;
parentSession.commit(receiver.getIntentSender());
@@ -691,7 +698,7 @@ class Rollback {
* Deletes app data snapshots associated with this rollback, and moves to the DELETED state.
*/
@WorkerThread
- void delete(AppDataRollbackHelper dataHelper) {
+ void delete(AppDataRollbackHelper dataHelper, @NonNull String reason) {
assertInWorkerThread();
boolean containsApex = false;
Set<Integer> apexUsers = new ArraySet<>();
@@ -717,7 +724,7 @@ class Rollback {
}
RollbackStore.deleteRollback(this);
- mState = ROLLBACK_STATE_DELETED;
+ setState(ROLLBACK_STATE_DELETED, reason);
}
/**
@@ -847,6 +854,7 @@ class Rollback {
case Rollback.ROLLBACK_STATE_ENABLING: return "enabling";
case Rollback.ROLLBACK_STATE_AVAILABLE: return "available";
case Rollback.ROLLBACK_STATE_COMMITTED: return "committed";
+ case Rollback.ROLLBACK_STATE_DELETED: return "deleted";
}
throw new AssertionError("Invalid rollback state: " + state);
}
@@ -858,6 +866,7 @@ class Rollback {
case "enabling": return Rollback.ROLLBACK_STATE_ENABLING;
case "available": return Rollback.ROLLBACK_STATE_AVAILABLE;
case "committed": return Rollback.ROLLBACK_STATE_COMMITTED;
+ case "deleted": return Rollback.ROLLBACK_STATE_DELETED;
}
throw new ParseException("Invalid rollback state: " + state, 0);
}
@@ -926,6 +935,7 @@ class Rollback {
ipw.println(info.getRollbackId() + ":");
ipw.increaseIndent();
ipw.println("-state: " + getStateAsString());
+ ipw.println("-stateDescription: " + mStateDescription);
ipw.println("-timestamp: " + getTimestamp());
if (getStagedSessionId() != -1) {
ipw.println("-stagedSessionId: " + getStagedSessionId());
@@ -955,4 +965,17 @@ class Rollback {
}
ipw.decreaseIndent();
}
+
+ @WorkerThread
+ String getStateDescription() {
+ assertInWorkerThread();
+ return mStateDescription;
+ }
+
+ @VisibleForTesting
+ void setState(@RollbackState int state, String description) {
+ assertInWorkerThread();
+ mState = state;
+ mStateDescription = description;
+ }
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index b34d46ff1a0c..192a00303a30 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -179,7 +179,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
mInstaller = new Installer(mContext);
mInstaller.onStart();
- mRollbackStore = new RollbackStore(new File(Environment.getDataDirectory(), "rollback"));
+ mRollbackStore = new RollbackStore(
+ new File(Environment.getDataDirectory(), "rollback"),
+ new File(Environment.getDataDirectory(), "rollback-history"));
mPackageHealthObserver = new RollbackPackageHealthObserver(mContext);
mAppDataRollbackHelper = new AppDataRollbackHelper(mInstaller);
@@ -201,7 +203,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
} else {
// Delete rollbacks when build fingerprint has changed.
for (Rollback rollback : mRollbacks) {
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, "Fingerprint changed");
}
mRollbacks.clear();
}
@@ -271,7 +273,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
Rollback rollback = getRollbackForSession(sessionId);
if (rollback != null && rollback.isEnabling()) {
mRollbacks.remove(rollback);
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, "Rollback canceled");
}
}
}
@@ -477,14 +479,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
}
@WorkerThread
- private void expireRollbackForPackageInternal(String packageName) {
+ private void expireRollbackForPackageInternal(String packageName, String reason) {
assertInWorkerThread();
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
if (rollback.includesPackage(packageName)) {
iter.remove();
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, reason);
}
}
}
@@ -496,7 +498,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
mContext.enforceCallingOrSelfPermission(
Manifest.permission.TEST_MANAGE_ROLLBACKS,
"expireRollbackForPackage");
- awaitResult(() -> expireRollbackForPackageInternal(packageName));
+ awaitResult(() -> expireRollbackForPackageInternal(packageName, "Expired by API"));
}
@ExtThread
@@ -612,7 +614,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
.getPackageInstaller().getSessionInfo(rollback.getStagedSessionId());
if (session == null || session.isStagedSessionFailed()) {
iter.remove();
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback,
+ "Session " + session.getSessionId() + " not existed or failed");
continue;
}
@@ -666,7 +669,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
&& rollback.includesPackageWithDifferentVersion(packageName,
installedVersion)) {
iter.remove();
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, "Package " + packageName + " replaced");
}
}
}
@@ -678,7 +681,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
@WorkerThread
private void onPackageFullyRemoved(String packageName) {
assertInWorkerThread();
- expireRollbackForPackageInternal(packageName);
+ expireRollbackForPackageInternal(packageName, "Package " + packageName + " removed");
}
/**
@@ -713,14 +716,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- if (!rollback.isAvailable()) {
+ if (!rollback.isAvailable() && !rollback.isCommitted()) {
continue;
}
Instant rollbackTimestamp = rollback.getTimestamp();
if (!now.isBefore(rollbackTimestamp.plusMillis(mRollbackLifetimeDurationInMillis))) {
Slog.i(TAG, "runExpiration id=" + rollback.info.getRollbackId());
iter.remove();
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, "Expired by timeout");
} else if (oldest == null || oldest.isAfter(rollbackTimestamp)) {
oldest = rollbackTimestamp;
}
@@ -1132,7 +1135,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
Slog.w(TAG, "Delete rollback id=" + rollback.info.getRollbackId()
+ " for failed session id=" + sessionId);
mRollbacks.remove(rollback);
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, "Session " + sessionId + " failed");
}
}
}
@@ -1159,7 +1162,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
if (!rollback.allPackagesEnabled()) {
Slog.e(TAG, "Failed to enable rollback for all packages in session.");
mRollbacks.remove(rollback);
- rollback.delete(mAppDataRollbackHelper);
+ deleteRollback(rollback, "Failed to enable rollback for all packages in session");
return false;
}
@@ -1240,6 +1243,18 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
rollback.dump(ipw);
}
ipw.println();
+
+ List<Rollback> historicalRollbacks = mRollbackStore.loadHistorialRollbacks();
+ if (!historicalRollbacks.isEmpty()) {
+ ipw.println("Historical rollbacks:");
+ ipw.increaseIndent();
+ for (Rollback rollback : historicalRollbacks) {
+ rollback.dump(ipw);
+ }
+ ipw.decreaseIndent();
+ ipw.println();
+ }
+
PackageWatchdog.getInstance(mContext).dump(ipw);
});
}
@@ -1329,4 +1344,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
}
return null;
}
+
+ @WorkerThread
+ private void deleteRollback(Rollback rollback, String reason) {
+ assertInWorkerThread();
+ rollback.delete(mAppDataRollbackHelper, reason);
+ mRollbackStore.saveRollbackToHistory(rollback);
+ }
}
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 2ee87e67e467..35c9f9ae6683 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -69,18 +69,20 @@ class RollbackStore {
// * XXX, YYY are the rollbackIds for the corresponding rollbacks.
// * rollback.json contains all relevant metadata for the rollback.
private final File mRollbackDataDir;
+ private final File mRollbackHistoryDir;
- RollbackStore(File rollbackDataDir) {
+ RollbackStore(File rollbackDataDir, File rollbackHistoryDir) {
mRollbackDataDir = rollbackDataDir;
+ mRollbackHistoryDir = rollbackHistoryDir;
}
/**
* Reads the rollbacks from persistent storage.
*/
- List<Rollback> loadRollbacks() {
+ private static List<Rollback> loadRollbacks(File rollbackDataDir) {
List<Rollback> rollbacks = new ArrayList<>();
- mRollbackDataDir.mkdirs();
- for (File rollbackDir : mRollbackDataDir.listFiles()) {
+ rollbackDataDir.mkdirs();
+ for (File rollbackDir : rollbackDataDir.listFiles()) {
if (rollbackDir.isDirectory()) {
try {
rollbacks.add(loadRollback(rollbackDir));
@@ -93,6 +95,14 @@ class RollbackStore {
return rollbacks;
}
+ List<Rollback> loadRollbacks() {
+ return loadRollbacks(mRollbackDataDir);
+ }
+
+ List<Rollback> loadHistorialRollbacks() {
+ return loadRollbacks(mRollbackHistoryDir);
+ }
+
/**
* Converts a {@code JSONArray} of integers to a {@code List<Integer>}.
*/
@@ -258,15 +268,17 @@ class RollbackStore {
/**
* Saves the given rollback to persistent storage.
*/
- static void saveRollback(Rollback rollback) {
+ private static void saveRollback(Rollback rollback, File backDir) {
FileOutputStream fos = null;
- AtomicFile file = new AtomicFile(new File(rollback.getBackupDir(), "rollback.json"));
+ AtomicFile file = new AtomicFile(new File(backDir, "rollback.json"));
try {
+ backDir.mkdirs();
JSONObject dataJson = new JSONObject();
dataJson.put("info", rollbackInfoToJson(rollback.info));
dataJson.put("timestamp", rollback.getTimestamp().toString());
dataJson.put("stagedSessionId", rollback.getStagedSessionId());
dataJson.put("state", rollback.getStateAsString());
+ dataJson.put("stateDescription", rollback.getStateDescription());
dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress());
dataJson.put("userId", rollback.getUserId());
dataJson.putOpt("installerPackageName", rollback.getInstallerPackageName());
@@ -286,6 +298,22 @@ class RollbackStore {
}
}
+ static void saveRollback(Rollback rollback) {
+ saveRollback(rollback, rollback.getBackupDir());
+ }
+
+ /**
+ * Saves the rollback to $mRollbackHistoryDir/ROLLBACKID-HEX for debugging purpose.
+ */
+ void saveRollbackToHistory(Rollback rollback) {
+ // The same id might be allocated to different historical rollbacks.
+ // Let's add a suffix to avoid naming collision.
+ String suffix = Long.toHexString(rollback.getTimestamp().getEpochSecond());
+ String dirName = Integer.toString(rollback.info.getRollbackId());
+ File backupDir = new File(mRollbackHistoryDir, dirName + "-" + suffix);
+ saveRollback(rollback, backupDir);
+ }
+
/**
* Removes all persistent storage associated with the given rollback.
*/
@@ -318,6 +346,7 @@ class RollbackStore {
Instant.parse(dataJson.getString("timestamp")),
dataJson.getInt("stagedSessionId"),
rollbackStateFromString(dataJson.getString("state")),
+ dataJson.optString("stateDescription"),
dataJson.getBoolean("restoreUserDataInProgress"),
dataJson.optInt("userId", UserHandle.SYSTEM.getIdentifier()),
dataJson.optString("installerPackageName", ""),
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 789dd5273094..7de0e87f91c3 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -132,7 +132,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
/** Internal method for handling the auto time setting being changed. */
@VisibleForTesting
public void handleAutoTimeDetectionChanged() {
- mHandler.post(mTimeDetectorStrategy::handleAutoTimeDetectionChanged);
+ mHandler.post(mTimeDetectorStrategy::handleAutoTimeConfigChanged);
}
@Override
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index 3b2b992c15ba..f278ef68c536 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -16,6 +16,7 @@
package com.android.server.timedetector;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.NetworkTimeSuggestion;
@@ -25,6 +26,9 @@ import android.util.IndentingPrintWriter;
import com.android.server.timezonedetector.Dumpable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* The interface for the class that implements the time detection algorithm used by the
* {@link TimeDetectorService}.
@@ -37,22 +41,41 @@ import com.android.server.timezonedetector.Dumpable;
*/
public interface TimeDetectorStrategy extends Dumpable {
- /** Process the suggested time from telephony sources. */
+ @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Origin {}
+
+ /** Used when a time value originated from a telephony signal. */
+ @Origin
+ int ORIGIN_TELEPHONY = 1;
+
+ /** Used when a time value originated from a user / manual settings. */
+ @Origin
+ int ORIGIN_MANUAL = 2;
+
+ /** Used when a time value originated from a network signal. */
+ @Origin
+ int ORIGIN_NETWORK = 3;
+
+ /** Processes the suggested time from telephony sources. */
void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion);
/**
- * Process the suggested manually entered time. Returns {@code false} if the suggestion was
+ * Processes the suggested manually entered time. Returns {@code false} if the suggestion was
* invalid, or the device configuration prevented the suggestion being used, {@code true} if the
* suggestion was accepted. A suggestion that is valid but does not change the time because it
* matches the current device time is considered accepted.
*/
boolean suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion);
- /** Process the suggested time from network sources. */
+ /** Processes the suggested time from network sources. */
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion);
- /** Handle the auto-time setting being toggled on or off. */
- void handleAutoTimeDetectionChanged();
+ /**
+ * Handles the auto-time configuration changing For example, when the auto-time setting is
+ * toggled on or off.
+ */
+ void handleAutoTimeConfigChanged();
// Utility methods below are to be moved to a better home when one becomes more obvious.
@@ -64,4 +87,38 @@ public interface TimeDetectorStrategy extends Dumpable {
return (referenceClockMillisNow - timeValue.getReferenceTimeMillis())
+ timeValue.getValue();
}
+
+ /**
+ * Converts one of the {@code ORIGIN_} constants to a human readable string suitable for config
+ * and debug usage. Throws an {@link IllegalArgumentException} if the value is unrecognized.
+ */
+ static String originToString(@Origin int origin) {
+ switch (origin) {
+ case ORIGIN_MANUAL:
+ return "manual";
+ case ORIGIN_NETWORK:
+ return "network";
+ case ORIGIN_TELEPHONY:
+ return "telephony";
+ default:
+ throw new IllegalArgumentException("origin=" + origin);
+ }
+ }
+
+ /**
+ * Converts a human readable config string to one of the {@code ORIGIN_} constants.
+ * Throws an {@link IllegalArgumentException} if the value is unrecognized.
+ */
+ static @Origin int stringToOrigin(String originString) {
+ switch (originString) {
+ case "manual":
+ return ORIGIN_MANUAL;
+ case "network":
+ return ORIGIN_NETWORK;
+ case "telephony":
+ return ORIGIN_TELEPHONY;
+ default:
+ throw new IllegalArgumentException("originString=" + originString);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
index e06fe9276323..5b6de0518999 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
@@ -16,16 +16,21 @@
package com.android.server.timedetector;
+import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
+
import android.annotation.NonNull;
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.os.Build;
+import android.os.Environment;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Slog;
+import java.time.Instant;
import java.util.Objects;
/**
@@ -38,6 +43,13 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
private static final int SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT = 2 * 1000;
/**
+ * Time in the past. If automatic time suggestion is before this point, it's
+ * incorrect for sure.
+ */
+ private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli(
+ Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
+
+ /**
* If a newly calculated system clock time and the current system clock time differs by this or
* more the system clock will actually be updated. Used to prevent the system clock being set
* for only minor differences.
@@ -48,6 +60,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
@NonNull private final ContentResolver mContentResolver;
@NonNull private final PowerManager.WakeLock mWakeLock;
@NonNull private final AlarmManager mAlarmManager;
+ @NonNull private final int[] mOriginPriorities;
public TimeDetectorStrategyCallbackImpl(@NonNull Context context) {
mContext = Objects.requireNonNull(context);
@@ -62,6 +75,15 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
mSystemClockUpdateThresholdMillis =
SystemProperties.getInt("ro.sys.time_detector_update_diff",
SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
+
+ // TODO(b/172230856): Obtain these values from configuration.
+ String[] originStrings = { "telephony", "network" };
+ int[] origins = new int[originStrings.length];
+ for (int i = 0; i < originStrings.length; i++) {
+ int origin = stringToOrigin(originStrings[i]);
+ origins[i] = origin;
+ }
+ mOriginPriorities = origins;
}
@Override
@@ -79,6 +101,16 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
}
@Override
+ public Instant autoTimeLowerBound() {
+ return TIME_LOWER_BOUND;
+ }
+
+ @Override
+ public int[] getAutoOriginPriorities() {
+ return mOriginPriorities;
+ }
+
+ @Override
public void acquireWakeLock() {
if (mWakeLock.isHeld()) {
Slog.wtf(TAG, "WakeLock " + mWakeLock + " already held");
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 7a2680bbe349..d8cada55781c 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -16,7 +16,8 @@
package com.android.server.timedetector;
-import android.annotation.IntDef;
+import static com.android.server.timedetector.TimeDetectorStrategy.originToString;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
@@ -33,8 +34,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.timezonedetector.ArrayMapWithHistory;
import com.android.server.timezonedetector.ReferenceWithHistory;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import java.time.Instant;
+import java.util.Arrays;
/**
* An implementation of {@link TimeDetectorStrategy} that passes telephony and manual suggestions to
@@ -62,22 +63,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
static final long MAX_UTC_TIME_AGE_MILLIS =
TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS;
- @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Origin {}
-
- /** Used when a time value originated from a telephony signal. */
- @Origin
- private static final int ORIGIN_TELEPHONY = 1;
-
- /** Used when a time value originated from a user / manual settings. */
- @Origin
- private static final int ORIGIN_MANUAL = 2;
-
- /** Used when a time value originated from a network signal. */
- @Origin
- private static final int ORIGIN_NETWORK = 3;
-
/**
* CLOCK_PARANOIA: The maximum difference allowed between the expected system clock time and the
* actual system clock time before a warning is logged. Used to help identify situations where
@@ -142,6 +127,21 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
/** Returns true if automatic time detection is enabled. */
boolean isAutoTimeDetectionEnabled();
+ /**
+ * Returns a lower bound for valid automatic times. It is guaranteed to be in the past,
+ * i.e. it is unrelated to the current system clock time.
+ * It holds no other meaning; it could be related to when the device system image was built,
+ * or could be updated by a mainline module.
+ */
+ @NonNull
+ Instant autoTimeLowerBound();
+
+ /**
+ * Returns the order to look at time suggestions when automatically detecting time.
+ * See {@code #ORIGIN_} constants
+ */
+ @Origin int[] getAutoOriginPriorities();
+
/** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */
void acquireWakeLock();
@@ -176,7 +176,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
@Override
public synchronized void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion) {
- if (!validateSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) {
+ if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) {
return;
}
@@ -210,9 +210,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return;
}
- // Perform validation / input filtering and record the validated suggestion against the
- // slotIndex.
- if (!validateAndStoreTelephonySuggestion(timeSuggestion)) {
+ if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) {
+ return;
+ }
+
+ // Perform input filtering and record the validated suggestion against the slotIndex.
+ if (!storeTelephonySuggestion(timeSuggestion)) {
return;
}
@@ -223,12 +226,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
}
@Override
- public synchronized void handleAutoTimeDetectionChanged() {
+ public synchronized void handleAutoTimeConfigChanged() {
boolean enabled = mCallback.isAutoTimeDetectionEnabled();
// When automatic time detection is enabled we update the system clock instantly if we can.
// Conversely, when automatic time detection is disabled we leave the clock as it is.
if (enabled) {
- String reason = "Auto time zone detection setting enabled.";
+ String reason = "Auto time zone detection config changed.";
doAutoTimeDetection(reason);
} else {
// CLOCK_PARANOIA: We are losing "control" of the system clock so we cannot predict what
@@ -269,14 +272,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
}
@GuardedBy("this")
- private boolean validateAndStoreTelephonySuggestion(
+ private boolean storeTelephonySuggestion(
@NonNull TelephonyTimeSuggestion suggestion) {
TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
- if (!validateSuggestionTime(newUtcTime, suggestion)) {
- // There's probably nothing useful we can do: elsewhere we assume that reference
- // times are in the past so just stop here.
- return false;
- }
int slotIndex = suggestion.getSlotIndex();
TelephonyTimeSuggestion previousSuggestion = mSuggestionBySlotIndex.get(slotIndex);
@@ -327,6 +325,26 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return true;
}
+ private boolean validateAutoSuggestionTime(
+ @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) {
+ return validateSuggestionTime(newUtcTime, suggestion)
+ && validateSuggestionAgainstLowerBound(newUtcTime, suggestion);
+ }
+
+ private boolean validateSuggestionAgainstLowerBound(
+ @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) {
+ Instant lowerBound = mCallback.autoTimeLowerBound();
+
+ // Suggestion is definitely wrong if it comes before lower time bound.
+ if (lowerBound.isAfter(Instant.ofEpochMilli(newUtcTime.getValue()))) {
+ Slog.w(LOG_TAG, "Suggestion points to time before lower bound, skipping it. "
+ + "suggestion=" + suggestion + ", lower bound=" + lowerBound);
+ return false;
+ }
+
+ return true;
+ }
+
@GuardedBy("this")
private void doAutoTimeDetection(@NonNull String detectionReason) {
if (!mCallback.isAutoTimeDetectionEnabled()) {
@@ -334,33 +352,44 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return;
}
- // Android devices currently prioritize any telephony over network signals. There are
- // carrier compliance tests that would need to be changed before we could ignore NITZ or
- // prefer NTP generally. This check is cheap on devices without telephony hardware.
- TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion();
- if (bestTelephonySuggestion != null) {
- final TimestampedValue<Long> newUtcTime = bestTelephonySuggestion.getUtcTime();
- String cause = "Found good telephony suggestion."
- + ", bestTelephonySuggestion=" + bestTelephonySuggestion
- + ", detectionReason=" + detectionReason;
- setSystemClockIfRequired(ORIGIN_TELEPHONY, newUtcTime, cause);
- return;
- }
+ // Try the different origins one at a time.
+ int[] originPriorities = mCallback.getAutoOriginPriorities();
+ for (int origin : originPriorities) {
+ TimestampedValue<Long> newUtcTime = null;
+ String cause = null;
+ if (origin == ORIGIN_TELEPHONY) {
+ TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion();
+ if (bestTelephonySuggestion != null) {
+ newUtcTime = bestTelephonySuggestion.getUtcTime();
+ cause = "Found good telephony suggestion."
+ + ", bestTelephonySuggestion=" + bestTelephonySuggestion
+ + ", detectionReason=" + detectionReason;
+ }
+ } else if (origin == ORIGIN_NETWORK) {
+ NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion();
+ if (networkSuggestion != null) {
+ newUtcTime = networkSuggestion.getUtcTime();
+ cause = "Found good network suggestion."
+ + ", networkSuggestion=" + networkSuggestion
+ + ", detectionReason=" + detectionReason;
+ }
+ } else {
+ Slog.w(LOG_TAG, "Unknown or unsupported origin=" + origin
+ + " in " + Arrays.toString(originPriorities)
+ + ": Skipping");
+ }
- // There is no good telephony suggestion, try network.
- NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion();
- if (networkSuggestion != null) {
- final TimestampedValue<Long> newUtcTime = networkSuggestion.getUtcTime();
- String cause = "Found good network suggestion."
- + ", networkSuggestion=" + networkSuggestion
- + ", detectionReason=" + detectionReason;
- setSystemClockIfRequired(ORIGIN_NETWORK, newUtcTime, cause);
- return;
+ // Update the system clock if a good suggestion has been found.
+ if (newUtcTime != null) {
+ setSystemClockIfRequired(origin, newUtcTime, cause);
+ return;
+ }
}
if (DBG) {
- Slog.d(LOG_TAG, "Could not determine time: No best telephony or network suggestion."
- + " detectionReason=" + detectionReason);
+ Slog.d(LOG_TAG, "Could not determine time: No suggestion found in"
+ + " originPriorities=" + Arrays.toString(originPriorities)
+ + ", detectionReason=" + detectionReason);
}
}
@@ -445,7 +474,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
// Validate first.
TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime();
if (!validateSuggestionUtcTime(elapsedRealtimeMillis, utcTime)) {
- Slog.w(LOG_TAG, "Existing suggestion found to be invalid "
+ Slog.w(LOG_TAG, "Existing suggestion found to be invalid"
+ " elapsedRealtimeMillis=" + elapsedRealtimeMillis
+ ", timeSuggestion=" + timeSuggestion);
return TELEPHONY_INVALID_SCORE;
@@ -494,7 +523,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
if (!mCallback.isAutoTimeDetectionEnabled()) {
if (DBG) {
Slog.d(LOG_TAG, "Auto time detection is not enabled."
- + " origin=" + origin
+ + " origin=" + originToString(origin)
+ ", time=" + time
+ ", cause=" + cause);
}
@@ -504,7 +533,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
if (mCallback.isAutoTimeDetectionEnabled()) {
if (DBG) {
Slog.d(LOG_TAG, "Auto time detection is enabled."
- + " origin=" + origin
+ + " origin=" + originToString(origin)
+ ", time=" + time
+ ", cause=" + cause);
}
@@ -526,7 +555,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
@GuardedBy("this")
private boolean setSystemClockUnderWakeLock(
- int origin, @NonNull TimestampedValue<Long> newTime, @NonNull Object cause) {
+ @Origin int origin, @NonNull TimestampedValue<Long> newTime, @NonNull String cause) {
long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
boolean isOriginAutomatic = isOriginAutomatic(origin);
diff --git a/services/core/java/com/android/server/uri/TEST_MAPPING b/services/core/java/com/android/server/uri/TEST_MAPPING
index e5cda03be25d..a9525f4a82ad 100644
--- a/services/core/java/com/android/server/uri/TEST_MAPPING
+++ b/services/core/java/com/android/server/uri/TEST_MAPPING
@@ -7,6 +7,26 @@
"include-filter": "com.android.server.uri."
}
]
+ },
+ {
+ "name": "CtsAppSecurityHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testGrantUriPermission"
+ },
+ {
+ "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testGrantUriPermission29"
+ },
+ {
+ "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone"
+ },
+ {
+ "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone28"
+ },
+ {
+ "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone29"
+ }
+ ]
}
],
"postsubmit": [
diff --git a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
new file mode 100644
index 000000000000..edbc05802697
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.util.SparseArray;
+import android.view.InputDevice;
+
+import com.android.internal.annotations.GuardedBy;
+
+/** Delegates vibrations to all connected {@link InputDevice} with available {@link Vibrator}. */
+// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
+public final class InputDeviceDelegate implements InputManager.InputDeviceListener {
+ private static final String TAG = "InputDeviceDelegate";
+
+ private final Object mLock = new Object();
+ private final Handler mHandler;
+ private final InputManager mInputManager;
+
+ @GuardedBy("mLock")
+ private final SparseArray<Vibrator> mInputDeviceVibrators = new SparseArray<>();
+
+ /**
+ * Flag updated via {@link #updateInputDeviceVibrators(boolean)}, holding the value of {@link
+ * android.provider.Settings.System#VIBRATE_INPUT_DEVICES}.
+ */
+ @GuardedBy("mLock")
+ private boolean mShouldVibrateInputDevices;
+
+ public InputDeviceDelegate(Context context, Handler handler) {
+ mHandler = handler;
+ mInputManager = context.getSystemService(InputManager.class);
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ updateInputDevice(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ updateInputDevice(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ synchronized (mLock) {
+ mInputDeviceVibrators.remove(deviceId);
+ }
+ }
+
+ /**
+ * Return {@code true} is there are input devices with vibrators available and vibrations should
+ * be delegated to them.
+ */
+ public boolean isAvailable() {
+ synchronized (mLock) {
+ // mInputDeviceVibrators is cleared when settings are disabled, so this check is enough.
+ return mInputDeviceVibrators.size() > 0;
+ }
+ }
+
+ /**
+ * Vibrate all {@link InputDevice} with {@link Vibrator} available using given effect.
+ *
+ * @return {@link #isAvailable()}
+ */
+ public boolean vibrateIfAvailable(int uid, String opPkg, VibrationEffect effect,
+ String reason, VibrationAttributes attrs) {
+ synchronized (mLock) {
+ for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
+ mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, effect, reason, attrs);
+ }
+ return mInputDeviceVibrators.size() > 0;
+ }
+ }
+
+ /**
+ * Cancel vibration on all {@link InputDevice} with {@link Vibrator} available.
+ *
+ * @return {@link #isAvailable()}
+ */
+ public boolean cancelVibrateIfAvailable() {
+ synchronized (mLock) {
+ for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
+ mInputDeviceVibrators.valueAt(i).cancel();
+ }
+ return mInputDeviceVibrators.size() > 0;
+ }
+ }
+
+ /**
+ * Updates the list of {@link InputDevice} vibrators based on the {@link
+ * VibrationSettings#shouldVibrateInputDevices()} setting current value and the
+ * devices currently available in {@link InputManager#getInputDeviceIds()}.
+ *
+ * @return true if there was any change in input devices available or related settings.
+ */
+ public boolean updateInputDeviceVibrators(boolean vibrateInputDevices) {
+ synchronized (mLock) {
+ if (vibrateInputDevices == mShouldVibrateInputDevices) {
+ // No need to update if settings haven't changed.
+ return false;
+ }
+
+ mShouldVibrateInputDevices = vibrateInputDevices;
+ mInputDeviceVibrators.clear();
+
+ if (vibrateInputDevices) {
+ // Register the listener first so any device added/updated/removed after the call to
+ // getInputDeviceIds() will trigger the callbacks (which will wait on the lock for
+ // this loop to finish).
+ mInputManager.registerInputDeviceListener(this, mHandler);
+
+ for (int deviceId : mInputManager.getInputDeviceIds()) {
+ InputDevice device = mInputManager.getInputDevice(deviceId);
+ if (device == null) {
+ continue;
+ }
+ Vibrator vibrator = device.getVibrator();
+ if (vibrator.hasVibrator()) {
+ mInputDeviceVibrators.put(device.getId(), vibrator);
+ }
+ }
+ } else {
+ mInputManager.unregisterInputDeviceListener(this);
+ }
+ }
+
+ return true;
+ }
+
+ private void updateInputDevice(int deviceId) {
+ synchronized (mLock) {
+ if (!mShouldVibrateInputDevices) {
+ // No need to keep this device vibrator if setting is off.
+ return;
+ }
+ InputDevice device = mInputManager.getInputDevice(deviceId);
+ if (device == null) {
+ mInputDeviceVibrators.remove(deviceId);
+ return;
+ }
+ Vibrator vibrator = device.getVibrator();
+ if (vibrator.hasVibrator()) {
+ mInputDeviceVibrators.put(deviceId, vibrator);
+ } else {
+ mInputDeviceVibrators.remove(deviceId);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
new file mode 100644
index 000000000000..e2cdd02deab9
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.server.ComposedProto;
+import com.android.server.OneShotProto;
+import com.android.server.PrebakedProto;
+import com.android.server.VibrationAttributesProto;
+import com.android.server.VibrationEffectProto;
+import com.android.server.VibrationProto;
+import com.android.server.WaveformProto;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/** Represents a vibration request to the vibrator service. */
+// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
+public class Vibration {
+ private static final String TAG = "Vibration";
+ private static final SimpleDateFormat DEBUG_DATE_FORMAT =
+ new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+
+ public enum Status {
+ RUNNING,
+ FINISHED,
+ FORWARDED_TO_INPUT_DEVICES,
+ CANCELLED,
+ ERROR_APP_OPS,
+ IGNORED,
+ IGNORED_APP_OPS,
+ IGNORED_BACKGROUND,
+ IGNORED_RINGTONE,
+ IGNORED_UNKNOWN_VIBRATION,
+ IGNORED_UNSUPPORTED,
+ IGNORED_FOR_ALARM,
+ IGNORED_FOR_EXTERNAL,
+ IGNORED_FOR_ONGOING,
+ IGNORED_FOR_POWER,
+ IGNORED_FOR_SETTINGS,
+ }
+
+ /** Start time in CLOCK_BOOTTIME base. */
+ public final long startTime;
+ public final VibrationAttributes attrs;
+ public final long id;
+ public final int uid;
+ public final String opPkg;
+ public final String reason;
+ public final IBinder token;
+
+ /** The actual effect to be played. */
+ @Nullable
+ private VibrationEffect mEffect;
+
+ /**
+ * The original effect that was requested. Typically these two things differ because the effect
+ * was scaled based on the users vibration intensity settings.
+ */
+ @Nullable
+ private VibrationEffect mOriginalEffect;
+
+ /**
+ * Start/end times in unix epoch time. Only to be used for debugging purposes and to correlate
+ * with other system events, any duration calculations should be done use {@link #startTime} so
+ * as not to be affected by discontinuities created by RTC adjustments.
+ */
+ private final long mStartTimeDebug;
+ private long mEndTimeDebug;
+ private Status mStatus;
+
+ public Vibration(IBinder token, int id, VibrationEffect effect,
+ VibrationAttributes attrs, int uid, String opPkg, String reason) {
+ this.token = token;
+ this.mEffect = effect;
+ this.id = id;
+ this.startTime = SystemClock.elapsedRealtime();
+ this.attrs = attrs;
+ this.uid = uid;
+ this.opPkg = opPkg;
+ this.reason = reason;
+ mStartTimeDebug = System.currentTimeMillis();
+ mStatus = Status.RUNNING;
+ }
+
+ /**
+ * Set the {@link Status} of this vibration and the current system time as this
+ * vibration end time, for debugging purposes.
+ *
+ * <p>This method will only accept given value if the current status is {@link
+ * Status#RUNNING}.
+ */
+ public void end(Status status) {
+ if (hasEnded()) {
+ // Vibration already ended, keep first ending status set and ignore this one.
+ return;
+ }
+ mStatus = status;
+ mEndTimeDebug = System.currentTimeMillis();
+ }
+
+ /**
+ * Replace this vibration effect if given {@code scaledEffect} is different, preserving the
+ * original one for debug purposes.
+ */
+ public void updateEffect(@NonNull VibrationEffect newEffect) {
+ if (newEffect.equals(mEffect)) {
+ return;
+ }
+ mOriginalEffect = mEffect;
+ mEffect = newEffect;
+ }
+
+ /** Return true is current status is different from {@link Status#RUNNING}. */
+ public boolean hasEnded() {
+ return mStatus != Status.RUNNING;
+ }
+
+ /** Return the effect that should be played by this vibration. */
+ @Nullable
+ public VibrationEffect getEffect() {
+ return mEffect;
+ }
+
+ /** Return {@link Vibration.DebugInfo} with read-only debug information about this vibration. */
+ public Vibration.DebugInfo getDebugInfo() {
+ return new Vibration.DebugInfo(
+ mStartTimeDebug, mEndTimeDebug, mEffect, mOriginalEffect, /* scale= */ 0, attrs,
+ uid, opPkg, reason, mStatus);
+ }
+
+ /** Debug information about vibrations. */
+ public static final class DebugInfo {
+ private final long mStartTimeDebug;
+ private final long mEndTimeDebug;
+ private final VibrationEffect mEffect;
+ private final VibrationEffect mOriginalEffect;
+ private final float mScale;
+ private final VibrationAttributes mAttrs;
+ private final int mUid;
+ private final String mOpPkg;
+ private final String mReason;
+ private final Status mStatus;
+
+ public DebugInfo(long startTimeDebug, long endTimeDebug, VibrationEffect effect,
+ VibrationEffect originalEffect, float scale, VibrationAttributes attrs,
+ int uid, String opPkg, String reason, Status status) {
+ mStartTimeDebug = startTimeDebug;
+ mEndTimeDebug = endTimeDebug;
+ mEffect = effect;
+ mOriginalEffect = originalEffect;
+ mScale = scale;
+ mAttrs = attrs;
+ mUid = uid;
+ mOpPkg = opPkg;
+ mReason = reason;
+ mStatus = status;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("startTime: ")
+ .append(DEBUG_DATE_FORMAT.format(new Date(mStartTimeDebug)))
+ .append(", endTime: ")
+ .append(mEndTimeDebug == 0 ? null
+ : DEBUG_DATE_FORMAT.format(new Date(mEndTimeDebug)))
+ .append(", status: ")
+ .append(mStatus.name().toLowerCase())
+ .append(", effect: ")
+ .append(mEffect)
+ .append(", originalEffect: ")
+ .append(mOriginalEffect)
+ .append(", scale: ")
+ .append(String.format("%.2f", mScale))
+ .append(", attrs: ")
+ .append(mAttrs)
+ .append(", uid: ")
+ .append(mUid)
+ .append(", opPkg: ")
+ .append(mOpPkg)
+ .append(", reason: ")
+ .append(mReason)
+ .toString();
+ }
+
+ /** Write this info into given {@code fieldId} on {@link ProtoOutputStream}. */
+ public void dumpProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(VibrationProto.START_TIME, mStartTimeDebug);
+ proto.write(VibrationProto.END_TIME, mEndTimeDebug);
+ proto.write(VibrationProto.STATUS, mStatus.ordinal());
+
+ final long attrsToken = proto.start(VibrationProto.ATTRIBUTES);
+ proto.write(VibrationAttributesProto.USAGE, mAttrs.getUsage());
+ proto.write(VibrationAttributesProto.AUDIO_USAGE, mAttrs.getAudioUsage());
+ proto.write(VibrationAttributesProto.FLAGS, mAttrs.getFlags());
+ proto.end(attrsToken);
+
+ if (mEffect != null) {
+ dumpEffect(proto, VibrationProto.EFFECT, mEffect);
+ }
+ if (mOriginalEffect != null) {
+ dumpEffect(proto, VibrationProto.ORIGINAL_EFFECT, mOriginalEffect);
+ }
+
+ proto.end(token);
+ }
+
+ private void dumpEffect(ProtoOutputStream proto, long fieldId, VibrationEffect effect) {
+ final long token = proto.start(fieldId);
+ if (effect instanceof VibrationEffect.OneShot) {
+ dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect);
+ } else if (effect instanceof VibrationEffect.Waveform) {
+ dumpEffect(proto, VibrationEffectProto.WAVEFORM, (VibrationEffect.Waveform) effect);
+ } else if (effect instanceof VibrationEffect.Prebaked) {
+ dumpEffect(proto, VibrationEffectProto.PREBAKED, (VibrationEffect.Prebaked) effect);
+ } else if (effect instanceof VibrationEffect.Composed) {
+ dumpEffect(proto, VibrationEffectProto.COMPOSED, (VibrationEffect.Composed) effect);
+ }
+ proto.end(token);
+ }
+
+ private void dumpEffect(ProtoOutputStream proto, long fieldId,
+ VibrationEffect.OneShot effect) {
+ final long token = proto.start(fieldId);
+ proto.write(OneShotProto.DURATION, (int) effect.getDuration());
+ proto.write(OneShotProto.AMPLITUDE, effect.getAmplitude());
+ proto.end(token);
+ }
+
+ private void dumpEffect(ProtoOutputStream proto, long fieldId,
+ VibrationEffect.Waveform effect) {
+ final long token = proto.start(fieldId);
+ for (long timing : effect.getTimings()) {
+ proto.write(WaveformProto.TIMINGS, (int) timing);
+ }
+ for (int amplitude : effect.getAmplitudes()) {
+ proto.write(WaveformProto.AMPLITUDES, amplitude);
+ }
+ proto.write(WaveformProto.REPEAT, effect.getRepeatIndex() >= 0);
+ proto.end(token);
+ }
+
+ private void dumpEffect(ProtoOutputStream proto, long fieldId,
+ VibrationEffect.Prebaked effect) {
+ final long token = proto.start(fieldId);
+ proto.write(PrebakedProto.EFFECT_ID, effect.getId());
+ proto.write(PrebakedProto.EFFECT_STRENGTH, effect.getEffectStrength());
+ proto.write(PrebakedProto.FALLBACK, effect.shouldFallback());
+ proto.end(token);
+ }
+
+ private void dumpEffect(ProtoOutputStream proto, long fieldId,
+ VibrationEffect.Composed effect) {
+ final long token = proto.start(fieldId);
+ for (VibrationEffect.Composition.PrimitiveEffect primitive :
+ effect.getPrimitiveEffects()) {
+ proto.write(ComposedProto.EFFECT_IDS, primitive.id);
+ proto.write(ComposedProto.EFFECT_SCALES, primitive.scale);
+ proto.write(ComposedProto.DELAYS, primitive.delay);
+ }
+ proto.end(token);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java
index 42a0a706a1c7..5f7e47d6ca29 100644
--- a/services/core/java/com/android/server/vibrator/VibrationScaler.java
+++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java
@@ -31,7 +31,6 @@ public final class VibrationScaler {
// Scale levels. Each level, except MUTE, is defined as the delta between the current setting
// and the default intensity for that type of vibration (i.e. current - default).
- private static final int SCALE_MUTE = IExternalVibratorService.SCALE_MUTE; // -100
private static final int SCALE_VERY_LOW = IExternalVibratorService.SCALE_VERY_LOW; // -2
private static final int SCALE_LOW = IExternalVibratorService.SCALE_LOW; // -1
private static final int SCALE_NONE = IExternalVibratorService.SCALE_NONE; // 0
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 06a1f599f491..6a5d1c4173c9 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -17,14 +17,17 @@
package com.android.server.vibrator;
import android.content.Context;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -37,6 +40,8 @@ import java.util.List;
public final class VibrationSettings {
private static final String TAG = "VibrationSettings";
+ private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = {0, 30, 100, 30};
+
/** Listener for changes on vibration settings. */
public interface OnVibratorSettingsChanged {
/** Callback triggered when any of the vibrator settings change. */
@@ -51,6 +56,7 @@ public final class VibrationSettings {
@GuardedBy("mLock")
private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
+ private final SparseArray<VibrationEffect> mFallbackEffects;
@GuardedBy("mLock")
private boolean mVibrateInputDevices;
@@ -84,6 +90,23 @@ public final class VibrationSettings {
registerSettingsObserver(
Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY));
+ VibrationEffect clickEffect = createEffectFromResource(
+ com.android.internal.R.array.config_virtualKeyVibePattern);
+ VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
+ DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS, -1 /*repeatIndex*/);
+ VibrationEffect heavyClickEffect = createEffectFromResource(
+ com.android.internal.R.array.config_longPressVibePattern);
+ VibrationEffect tickEffect = createEffectFromResource(
+ com.android.internal.R.array.config_clockTickVibePattern);
+
+ mFallbackEffects = new SparseArray<>();
+ mFallbackEffects.put(VibrationEffect.EFFECT_CLICK, clickEffect);
+ mFallbackEffects.put(VibrationEffect.EFFECT_DOUBLE_CLICK, doubleClickEffect);
+ mFallbackEffects.put(VibrationEffect.EFFECT_TICK, tickEffect);
+ mFallbackEffects.put(VibrationEffect.EFFECT_HEAVY_CLICK, heavyClickEffect);
+ mFallbackEffects.put(VibrationEffect.EFFECT_TEXTURE_TICK,
+ VibrationEffect.get(VibrationEffect.EFFECT_TICK, false));
+
// Update with current values from settings.
updateSettings();
}
@@ -150,6 +173,17 @@ public final class VibrationSettings {
}
/**
+ * Return a {@link VibrationEffect} that should be played if the device do not support given
+ * {@code effectId}.
+ *
+ * @param effectId one of VibrationEffect.EFFECT_*
+ * @return The effect to be played as a fallback
+ */
+ public VibrationEffect getFallbackEffect(int effectId) {
+ return mFallbackEffects.get(effectId);
+ }
+
+ /**
* Return {@code true} if the device should vibrate for ringtones.
*
* <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings
@@ -270,6 +304,33 @@ public final class VibrationSettings {
UserHandle.USER_ALL);
}
+ private VibrationEffect createEffectFromResource(int resId) {
+ long[] timings = getLongIntArray(mContext.getResources(), resId);
+ return createEffectFromTimings(timings);
+ }
+
+ private static VibrationEffect createEffectFromTimings(long[] timings) {
+ if (timings == null || timings.length == 0) {
+ return null;
+ } else if (timings.length == 1) {
+ return VibrationEffect.createOneShot(timings[0], VibrationEffect.DEFAULT_AMPLITUDE);
+ } else {
+ return VibrationEffect.createWaveform(timings, -1);
+ }
+ }
+
+ private static long[] getLongIntArray(Resources r, int resid) {
+ int[] ar = r.getIntArray(resid);
+ if (ar == null) {
+ return null;
+ }
+ long[] out = new long[ar.length];
+ for (int i = 0; i < ar.length; i++) {
+ out[i] = ar[i];
+ }
+ return out;
+ }
+
/** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
private final class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java
new file mode 100644
index 000000000000..f76c1a1b2b9d
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/VibratorController.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.annotation.Nullable;
+import android.hardware.vibrator.IVibrator;
+import android.os.Binder;
+import android.os.IVibratorStateListener;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/** Controls a single vibrator. */
+// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
+public final class VibratorController {
+ private static final String TAG = "VibratorController";
+
+ private final Object mLock = new Object();
+ private final NativeWrapper mNativeWrapper;
+ private final int mVibratorId;
+ private final long mCapabilities;
+ @Nullable
+ private final Set<Integer> mSupportedEffects;
+ @Nullable
+ private final Set<Integer> mSupportedPrimitives;
+
+ @GuardedBy("mLock")
+ private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners =
+ new RemoteCallbackList<>();
+ @GuardedBy("mLock")
+ private boolean mIsVibrating;
+ @GuardedBy("mLock")
+ private boolean mIsUnderExternalControl;
+
+ /** Listener for vibration completion callbacks from native. */
+ public interface OnVibrationCompleteListener {
+
+ /** Callback triggered when vibration is complete. */
+ void onComplete(int vibratorId, long vibrationId);
+ }
+
+ /**
+ * Initializes the native part of this controller, creating a global reference to given
+ * {@link OnVibrationCompleteListener} and returns a newly allocated native pointer. This
+ * wrapper is responsible for deleting this pointer by calling the method pointed
+ * by {@link #vibratorGetFinalizer()}.
+ *
+ * <p><b>Note:</b> Make sure the given implementation of {@link OnVibrationCompleteListener}
+ * do not hold any strong reference to the instance responsible for deleting the returned
+ * pointer, to avoid creating a cyclic GC root reference.
+ */
+ static native long vibratorInit(int vibratorId, OnVibrationCompleteListener listener);
+
+ /**
+ * Returns pointer to native function responsible for cleaning up the native pointer allocated
+ * and returned by {@link #vibratorInit(int, OnVibrationCompleteListener)}.
+ */
+ static native long vibratorGetFinalizer();
+
+ static native boolean vibratorIsAvailable(long nativePtr);
+
+ static native void vibratorOn(long nativePtr, long milliseconds, long vibrationId);
+
+ static native void vibratorOff(long nativePtr);
+
+ static native void vibratorSetAmplitude(long nativePtr, int amplitude);
+
+ static native int[] vibratorGetSupportedEffects(long nativePtr);
+
+ static native int[] vibratorGetSupportedPrimitives(long nativePtr);
+
+ static native long vibratorPerformEffect(
+ long nativePtr, long effect, long strength, long vibrationId);
+
+ static native void vibratorPerformComposedEffect(long nativePtr,
+ VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId);
+
+ static native void vibratorSetExternalControl(long nativePtr, boolean enabled);
+
+ static native long vibratorGetCapabilities(long nativePtr);
+
+ static native void vibratorAlwaysOnEnable(long nativePtr, long id, long effect, long strength);
+
+ static native void vibratorAlwaysOnDisable(long nativePtr, long id);
+
+ public VibratorController(int vibratorId, OnVibrationCompleteListener listener) {
+ this(vibratorId, listener, new NativeWrapper());
+ }
+
+ @VisibleForTesting
+ public VibratorController(int vibratorId, OnVibrationCompleteListener listener,
+ NativeWrapper nativeWrapper) {
+ mVibratorId = vibratorId;
+ mNativeWrapper = nativeWrapper;
+
+ nativeWrapper.init(vibratorId, listener);
+ mCapabilities = nativeWrapper.getCapabilities();
+ mSupportedEffects = asSet(nativeWrapper.getSupportedEffects());
+ mSupportedPrimitives = asSet(nativeWrapper.getSupportedPrimitives());
+ }
+
+ /** Register state listener for this vibrator. */
+ public boolean registerVibratorStateListener(IVibratorStateListener listener) {
+ synchronized (mLock) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ if (!mVibratorStateListeners.register(listener)) {
+ return false;
+ }
+ // Notify its callback after new client registered.
+ notifyStateListenerLocked(listener);
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ /** Remove registered state listener for this vibrator. */
+ public boolean unregisterVibratorStateListener(IVibratorStateListener listener) {
+ synchronized (mLock) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return mVibratorStateListeners.unregister(listener);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ /** Return the id of the vibrator controlled by this instance. */
+ public int getVibratorId() {
+ return mVibratorId;
+ }
+
+ /**
+ * Return {@code true} is this vibrator is currently vibrating, false otherwise.
+ *
+ * <p>This state is controlled by calls to {@link #on} and {@link #off} methods, and is
+ * automatically notified to any registered {@link IVibratorStateListener} on change.
+ */
+ public boolean isVibrating() {
+ synchronized (mLock) {
+ return mIsVibrating;
+ }
+ }
+
+ /** Return {@code true} if this vibrator is under external control, false otherwise. */
+ public boolean isUnderExternalControl() {
+ synchronized (mLock) {
+ return mIsUnderExternalControl;
+ }
+ }
+
+ /**
+ * Check against this vibrator capabilities.
+ *
+ * @param capability one of IVibrator.CAP_*
+ * @return true if this vibrator has this capability, false otherwise
+ */
+ public boolean hasCapability(long capability) {
+ return (mCapabilities & capability) == capability;
+ }
+
+ /**
+ * Check against this vibrator supported effects.
+ *
+ * @param effectIds list of effects, one of VibrationEffect.EFFECT_*
+ * @return one entry per requested effectId, with one of Vibrator.VIBRATION_EFFECT_SUPPORT_*
+ */
+ public int[] areEffectsSupported(int[] effectIds) {
+ int[] supported = new int[effectIds.length];
+ if (mSupportedEffects == null) {
+ Arrays.fill(supported, Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN);
+ } else {
+ for (int i = 0; i < effectIds.length; i++) {
+ supported[i] = mSupportedEffects.contains(effectIds[i])
+ ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES
+ : Vibrator.VIBRATION_EFFECT_SUPPORT_NO;
+ }
+ }
+ return supported;
+ }
+
+ /**
+ * Check against this vibrator supported primitives.
+ *
+ * @param primitiveIds list of primitives, one of VibrationEffect.Composition.EFFECT_*
+ * @return one entry per requested primitiveId, with true if it is supported
+ */
+ public boolean[] arePrimitivesSupported(int[] primitiveIds) {
+ boolean[] supported = new boolean[primitiveIds.length];
+ if (mSupportedPrimitives != null && hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
+ for (int i = 0; i < primitiveIds.length; i++) {
+ supported[i] = mSupportedPrimitives.contains(primitiveIds[i]);
+ }
+ }
+ return supported;
+ }
+
+ /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */
+ public boolean isAvailable() {
+ return mNativeWrapper.isAvailable();
+ }
+
+ /**
+ * Set the vibrator control to be external or not, based on given flag.
+ *
+ * <p>This will affect the state of {@link #isUnderExternalControl()}.
+ */
+ public void setExternalControl(boolean externalControl) {
+ if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
+ return;
+ }
+ synchronized (mLock) {
+ mIsUnderExternalControl = externalControl;
+ mNativeWrapper.setExternalControl(externalControl);
+ }
+ }
+
+ /**
+ * Update the predefined vibration effect saved with given id. This will remove the saved effect
+ * if given {@code effect} is {@code null}.
+ */
+ public void updateAlwaysOn(int id, @Nullable VibrationEffect.Prebaked effect) {
+ if (!hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) {
+ return;
+ }
+ synchronized (mLock) {
+ if (effect == null) {
+ mNativeWrapper.alwaysOnDisable(id);
+ } else {
+ mNativeWrapper.alwaysOnEnable(id, effect.getId(), effect.getEffectStrength());
+ }
+ }
+ }
+
+ /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */
+ public void setAmplitude(int amplitude) {
+ synchronized (mLock) {
+ if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
+ mNativeWrapper.setAmplitude(amplitude);
+ }
+ }
+ }
+
+ /**
+ * Turn on the vibrator for {@code milliseconds} time, using {@code vibrationId} or completion
+ * callback to {@link OnVibrationCompleteListener}.
+ *
+ * <p>This will affect the state of {@link #isVibrating()}.
+ */
+ public void on(long milliseconds, long vibrationId) {
+ synchronized (mLock) {
+ mNativeWrapper.on(milliseconds, vibrationId);
+ notifyVibratorOnLocked();
+ }
+ }
+
+ /**
+ * Plays predefined vibration effect, using {@code vibrationId} or completion callback to
+ * {@link OnVibrationCompleteListener}.
+ *
+ * <p>This will affect the state of {@link #isVibrating()}.
+ */
+ public long on(VibrationEffect.Prebaked effect, long vibrationId) {
+ synchronized (mLock) {
+ long duration = mNativeWrapper.perform(effect.getId(), effect.getEffectStrength(),
+ vibrationId);
+ if (duration > 0) {
+ notifyVibratorOnLocked();
+ }
+ return duration;
+ }
+ }
+
+ /**
+ * Plays composited vibration effect, using {@code vibrationId} or completion callback to
+ * {@link OnVibrationCompleteListener}.
+ *
+ * <p>This will affect the state of {@link #isVibrating()}.
+ */
+ public void on(VibrationEffect.Composed effect, long vibrationId) {
+ if (!hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
+ return;
+ }
+ synchronized (mLock) {
+ mNativeWrapper.compose(effect.getPrimitiveEffects().toArray(
+ new VibrationEffect.Composition.PrimitiveEffect[0]), vibrationId);
+ notifyVibratorOnLocked();
+ }
+ }
+
+ /** Turns off the vibrator.This will affect the state of {@link #isVibrating()}. */
+ public void off() {
+ synchronized (mLock) {
+ mNativeWrapper.off();
+ notifyVibratorOffLocked();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "VibratorController{"
+ + "mVibratorId=" + mVibratorId
+ + ", mCapabilities=" + mCapabilities
+ + ", mSupportedEffects=" + mSupportedEffects
+ + ", mSupportedPrimitives=" + mSupportedPrimitives
+ + ", mIsVibrating=" + mIsVibrating
+ + ", mIsUnderExternalControl=" + mIsUnderExternalControl
+ + ", mVibratorStateListeners count="
+ + mVibratorStateListeners.getRegisteredCallbackCount()
+ + '}';
+ }
+
+ @GuardedBy("mLock")
+ private void notifyVibratorOnLocked() {
+ if (!mIsVibrating) {
+ mIsVibrating = true;
+ notifyStateListenersLocked();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void notifyVibratorOffLocked() {
+ if (mIsVibrating) {
+ mIsVibrating = false;
+ notifyStateListenersLocked();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void notifyStateListenersLocked() {
+ final int length = mVibratorStateListeners.beginBroadcast();
+ try {
+ for (int i = 0; i < length; i++) {
+ notifyStateListenerLocked(mVibratorStateListeners.getBroadcastItem(i));
+ }
+ } finally {
+ mVibratorStateListeners.finishBroadcast();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void notifyStateListenerLocked(IVibratorStateListener listener) {
+ try {
+ listener.onVibrating(mIsVibrating);
+ } catch (RemoteException | RuntimeException e) {
+ Slog.e(TAG, "Vibrator state listener failed to call", e);
+ }
+ }
+
+ @Nullable
+ private static Set<Integer> asSet(int[] values) {
+ if (values == null) {
+ return null;
+ }
+ HashSet<Integer> set = new HashSet<>();
+ for (int value : values) {
+ set.add(value);
+ }
+ return set;
+ }
+
+ /** Wrapper around the static-native methods of {@link VibratorController} for tests. */
+ @VisibleForTesting
+ public static class NativeWrapper {
+
+ private long mNativePtr = 0;
+
+ /** Initializes native controller and allocation registry to destroy native instances. */
+ public void init(int vibratorId, OnVibrationCompleteListener listener) {
+ mNativePtr = VibratorController.vibratorInit(vibratorId, listener);
+ long finalizerPtr = VibratorController.vibratorGetFinalizer();
+
+ if (finalizerPtr != 0) {
+ NativeAllocationRegistry registry =
+ NativeAllocationRegistry.createMalloced(
+ VibratorController.class.getClassLoader(), finalizerPtr);
+ registry.registerNativeAllocation(this, mNativePtr);
+ }
+ }
+
+ /** Check if the vibrator is currently available. */
+ public boolean isAvailable() {
+ return VibratorController.vibratorIsAvailable(mNativePtr);
+ }
+
+ /** Turns vibrator on for given time. */
+ public void on(long milliseconds, long vibrationId) {
+ VibratorController.vibratorOn(mNativePtr, milliseconds, vibrationId);
+ }
+
+ /** Turns vibrator off. */
+ public void off() {
+ VibratorController.vibratorOff(mNativePtr);
+ }
+
+ /** Sets the amplitude for the vibrator to run. */
+ public void setAmplitude(int amplitude) {
+ VibratorController.vibratorSetAmplitude(mNativePtr, amplitude);
+ }
+
+ /** Returns all predefined effects supported by the device vibrator. */
+ public int[] getSupportedEffects() {
+ return VibratorController.vibratorGetSupportedEffects(mNativePtr);
+ }
+
+ /** Returns all compose primitives supported by the device vibrator. */
+ public int[] getSupportedPrimitives() {
+ return VibratorController.vibratorGetSupportedPrimitives(mNativePtr);
+ }
+
+ /** Turns vibrator on to perform one of the supported effects. */
+ public long perform(long effect, long strength, long vibrationId) {
+ return VibratorController.vibratorPerformEffect(
+ mNativePtr, effect, strength, vibrationId);
+ }
+
+ /** Turns vibrator on to perform one of the supported composed effects. */
+ public void compose(
+ VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) {
+ VibratorController.vibratorPerformComposedEffect(mNativePtr, effect,
+ vibrationId);
+ }
+
+ /** Enabled the device vibrator to be controlled by another service. */
+ public void setExternalControl(boolean enabled) {
+ VibratorController.vibratorSetExternalControl(mNativePtr, enabled);
+ }
+
+ /** Returns all capabilities of the device vibrator. */
+ public long getCapabilities() {
+ return VibratorController.vibratorGetCapabilities(mNativePtr);
+ }
+
+ /** Enable always-on vibration with given id and effect. */
+ public void alwaysOnEnable(long id, long effect, long strength) {
+ VibratorController.vibratorAlwaysOnEnable(mNativePtr, id, effect, strength);
+ }
+
+ /** Disable always-on vibration for given id. */
+ public void alwaysOnDisable(long id) {
+ VibratorController.vibratorAlwaysOnDisable(mNativePtr, id);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c2016decdbe9..913c3e580adf 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7584,6 +7584,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
}
+ String getProcessName() {
+ return info.applicationInfo.processName;
+ }
+
int getUid() {
return info.applicationInfo.uid;
}
@@ -7596,6 +7600,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return app != null ? app.getPid() : 0;
}
+ int getLaunchedFromPid() {
+ return launchedFromPid;
+ }
+
+ int getLaunchedFromUid() {
+ return launchedFromUid;
+ }
+
/**
* Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
* {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index acee7b26725e..b88b54ef08f5 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -57,9 +57,6 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
-import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
-import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
@@ -71,6 +68,9 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
+import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
+import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
+import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
import static com.android.server.wm.Task.ActivityState.RESUMED;
@@ -1870,7 +1870,7 @@ class ActivityStarter {
}
mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
- sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams);
+ sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams, mRequest);
mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
? mLaunchParams.mPreferredTaskDisplayArea
: mRootWindowContainer.getDefaultTaskDisplayArea();
@@ -2031,12 +2031,12 @@ class ActivityStarter {
*/
private int deliverToCurrentTopIfNeeded(Task topStack, NeededUriGrants intentGrants) {
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
- final boolean dontStart = top != null && mStartActivity.resultTo == null
+ final boolean dontStart = top != null
&& top.mActivityComponent.equals(mStartActivity.mActivityComponent)
&& top.mUserId == mStartActivity.mUserId
&& top.attachedToProcess()
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
- || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
+ || LAUNCH_SINGLE_TOP == mLaunchMode)
// This allows home activity to automatically launch on secondary task display area
// when it was added, if home was the top activity on default task display area,
// instead of sending new intent to the home activity on default display area.
@@ -2057,6 +2057,13 @@ class ActivityStarter {
return START_RETURN_INTENT_TO_CALLER;
}
+ if (mStartActivity.resultTo != null) {
+ mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
+ mStartActivity.requestCode, RESULT_CANCELED,
+ null /* data */, null /* dataGrants */);
+ mStartActivity.resultTo = null;
+ }
+
deliverNewIntent(top, intentGrants);
// Don't use mStartActivity.task to show the toast. We're not starting a new activity but
@@ -2254,7 +2261,7 @@ class ActivityStarter {
// Preferred display id is the only state we need for now and it could be updated again
// after we located a reusable task (which might be resided in another display).
mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
- sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
+ sourceRecord, options, PHASE_DISPLAY, mLaunchParams, mRequest);
mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
? mLaunchParams.mPreferredTaskDisplayArea
: mRootWindowContainer.getDefaultTaskDisplayArea();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 27faf13e2999..e12dc2bd56a8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1056,7 +1056,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
- public void onUserUnlocking(@NonNull TargetUser user) {
+ public void onUserUnlocked(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
mService.mTaskSupervisor.onUserUnlocked(user.getUserIdentifier());
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 1064e6aa357c..d0c26af82d99 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -186,7 +186,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
- private static final int REPORT_HOME_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 16;
+ private static final int START_HOME_MSG = FIRST_SUPERVISOR_STACK_MSG + 16;
private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 17;
// Used to indicate that windows of activities should be preserved during the resize.
@@ -446,6 +446,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// unlocked.
mPersisterQueue.startPersisting();
mLaunchParamsPersister.onUnlockUser(userId);
+
+ // Need to launch home again for those displays that do not have encryption aware home app.
+ scheduleStartHome("userUnlocked");
}
public ActivityMetricsLogger getActivityMetricsLogger() {
@@ -956,13 +959,17 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
void updateHomeProcess(WindowProcessController app) {
if (app != null && mService.mHomeProcess != app) {
- if (!mHandler.hasMessages(REPORT_HOME_CHANGED_MSG)) {
- mHandler.sendEmptyMessage(REPORT_HOME_CHANGED_MSG);
- }
+ scheduleStartHome("homeChanged");
mService.mHomeProcess = app;
}
}
+ private void scheduleStartHome(String reason) {
+ if (!mHandler.hasMessages(START_HOME_MSG)) {
+ mHandler.obtainMessage(START_HOME_MSG, reason).sendToTarget();
+ }
+ }
+
private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
int extrasSize = 0;
if (intent != null) {
@@ -2473,11 +2480,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
handleLaunchTaskBehindCompleteLocked(r);
}
} break;
- case REPORT_HOME_CHANGED_MSG: {
- mHandler.removeMessages(REPORT_HOME_CHANGED_MSG);
+ case START_HOME_MSG: {
+ mHandler.removeMessages(START_HOME_MSG);
// Start home activities on displays with no activities.
- mRootWindowContainer.startHomeOnEmptyDisplays("homeChanged");
+ mRootWindowContainer.startHomeOnEmptyDisplays((String) msg.obj);
} break;
case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: {
final ActivityRecord r = (ActivityRecord) msg.obj;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4133ea2b2a7b..ccc85f834bc1 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -73,6 +73,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
@@ -91,7 +93,7 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_C
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
-import static com.android.server.wm.DisplayContentProto.CAN_SHOW_IME;
+import static com.android.server.wm.DisplayContentProto.IME_POLICY;
import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS;
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
@@ -203,6 +205,7 @@ import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
import com.android.internal.annotations.VisibleForTesting;
@@ -2930,7 +2933,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mInsetsStateController.getImeSourceProvider().dumpDebug(proto,
IME_INSETS_SOURCE_PROVIDER, logLevel);
}
- proto.write(CAN_SHOW_IME, canShowIme());
+ proto.write(IME_POLICY, getImePolicy());
proto.end(token);
}
@@ -3561,7 +3564,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* @return {@link InsetsControlTarget} that can host IME.
*/
InsetsControlTarget getImeHostOrFallback(WindowState target) {
- if (target != null && target.getDisplayContent().canShowIme()) {
+ if (target != null
+ && target.getDisplayContent().getImePolicy() == DISPLAY_IME_POLICY_LOCAL) {
return target;
}
return getImeFallback();
@@ -3575,12 +3579,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return statusBar != null ? statusBar : defaultDc.mRemoteInsetsControlTarget;
}
- boolean canShowIme() {
+ @DisplayImePolicy int getImePolicy() {
if (!isTrusted()) {
- return false;
+ return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+ }
+ final int imePolicy = mWmService.mDisplayWindowSettings.getImePolicyLocked(this);
+ if (imePolicy == DISPLAY_IME_POLICY_FALLBACK_DISPLAY && forceDesktopMode()) {
+ // If the display has not explicitly requested for the IME to be hidden then it shall
+ // show the IME locally.
+ return DISPLAY_IME_POLICY_LOCAL;
}
- return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this)
- || forceDesktopMode();
+ return imePolicy;
}
boolean forceDesktopMode() {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index f14a2ee8e7ee..826b7259a9ff 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -66,7 +66,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BA
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -279,7 +278,6 @@ public class DisplayPolicy {
private volatile boolean mKeyguardDrawComplete;
private volatile boolean mWindowManagerDrawComplete;
- private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>();
private WindowState mStatusBar = null;
private WindowState mNotificationShade = null;
private final int[] mStatusBarHeightForRotation = new int[4];
@@ -864,19 +862,7 @@ public class DisplayPolicy {
* @param attrs The window layout parameters to be modified. These values
* are modified in-place.
*/
- public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
- int callingPid, int callingUid) {
-
- final boolean isScreenDecor = (attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0;
- if (mScreenDecorWindows.contains(win)) {
- if (!isScreenDecor) {
- // No longer has the flag set, so remove from the set.
- mScreenDecorWindows.remove(win);
- }
- } else if (isScreenDecor && hasStatusBarServicePermission(callingPid, callingUid)) {
- mScreenDecorWindows.add(win);
- }
-
+ public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs) {
switch (attrs.type) {
case TYPE_SYSTEM_OVERLAY:
case TYPE_SECURE_SYSTEM_OVERLAY:
@@ -966,11 +952,6 @@ public class DisplayPolicy {
* WindowManagerImpl.ADD_MULTIPLE_SINGLETON
*/
int validateAddingWindowLw(WindowManager.LayoutParams attrs, int callingPid, int callingUid) {
- if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
- mContext.enforcePermission(
- android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
- "DisplayPolicy");
- }
if ((attrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
mContext.enforcePermission(
android.Manifest.permission.INTERNAL_SYSTEM_WINDOW, callingPid, callingUid,
@@ -1090,10 +1071,6 @@ public class DisplayPolicy {
* @param attrs Information about the window to be added.
*/
void addWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
- if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
- mScreenDecorWindows.add(win);
- }
-
switch (attrs.type) {
case TYPE_NOTIFICATION_SHADE:
mNotificationShade = win;
@@ -1275,7 +1252,6 @@ public class DisplayPolicy {
if (mLastFocusedWindow == win) {
mLastFocusedWindow = null;
}
- mScreenDecorWindows.remove(win);
}
private int getStatusBarHeight(DisplayFrames displayFrames) {
@@ -1457,14 +1433,12 @@ public class DisplayPolicy {
}
final int fl = attrs.flags;
- final int pfl = attrs.privateFlags;
final boolean layoutInScreenAndInsetDecor = (fl & FLAG_LAYOUT_IN_SCREEN) != 0
&& (fl & FLAG_LAYOUT_INSET_DECOR) != 0;
- final boolean screenDecor = (pfl & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0;
final DisplayFrames displayFrames = isFixedRotationTransforming
? windowToken.getFixedRotationTransformDisplayFrames()
: mDisplayContent.mDisplayFrames;
- if (layoutInScreenAndInsetDecor && !screenDecor) {
+ if (layoutInScreenAndInsetDecor) {
outDisplayCutout.set(
displayFrames.mDisplayCutout.calculateRelativeTo(outFrame).getDisplayCutout());
} else {
@@ -1564,7 +1538,6 @@ public class DisplayPolicy {
simulatedWindowFrames, barContentFrames,
contentFrame -> layoutStatusBar(displayFrames, contentFrame));
}
- layoutScreenDecorWindows(displayFrames, simulatedWindowFrames);
}
/**
@@ -1585,7 +1558,6 @@ public class DisplayPolicy {
layoutNavigationBar(displayFrames, uiMode, null /* simulatedContentFrame */);
layoutStatusBar(displayFrames, null /* simulatedContentFrame */);
- layoutScreenDecorWindows(displayFrames, null /* simulatedFrames */);
}
void updateHideNavInputEventReceiver() {
@@ -1640,47 +1612,6 @@ public class DisplayPolicy {
state.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame(u.left, s.bottom, u.right, u.bottom);
}
- /**
- * Layout the decor windows with {@link #PRIVATE_FLAG_IS_SCREEN_DECOR}.
- *
- * @param displayFrames The display frames to be layouted.
- * @param simulatedFrames Non-null if the caller only needs the result of display frames (see
- * {@link WindowState#mSimulatedWindowFrames}).
- */
- private void layoutScreenDecorWindows(DisplayFrames displayFrames,
- WindowFrames simulatedFrames) {
- if (mScreenDecorWindows.isEmpty()) {
- return;
- }
-
- sTmpRect.setEmpty();
- final int displayId = displayFrames.mDisplayId;
-
- for (int i = mScreenDecorWindows.size() - 1; i >= 0; --i) {
- final WindowState w = mScreenDecorWindows.valueAt(i);
- if (w.getDisplayId() != displayId || !w.isVisible()) {
- // Skip if not on the same display or not visible.
- continue;
- }
-
- final boolean isSimulatedLayout = simulatedFrames != null;
- if (isSimulatedLayout) {
- w.setSimulatedWindowFrames(simulatedFrames);
- }
- getRotatedWindowBounds(displayFrames, w, sTmpScreenDecorFrame);
- final WindowFrames windowFrames = w.getLayoutingWindowFrames();
- windowFrames.setFrames(sTmpScreenDecorFrame /* parentFrame */,
- sTmpScreenDecorFrame /* displayFrame */);
- try {
- w.computeFrame(displayFrames);
- } finally {
- if (isSimulatedLayout) {
- w.setSimulatedWindowFrames(null);
- }
- }
- }
- }
-
private void layoutStatusBar(DisplayFrames displayFrames, Rect simulatedContentFrame) {
// decide where the status bar goes ahead of time
if (mStatusBar == null) {
@@ -1819,8 +1750,7 @@ public class DisplayPolicy {
// We've already done the navigation bar, status bar, and all screen decor windows. If the
// status bar can receive input, we need to layout it again to accommodate for the IME
// window.
- if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar
- || mScreenDecorWindows.contains(win)) {
+ if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar) {
return;
}
final WindowManager.LayoutParams attrs = win.getAttrs();
@@ -2772,7 +2702,11 @@ public class DisplayPolicy {
&& mLastDockedStackBounds.equals(mDockedStackBounds)) {
return false;
}
-
+ if (mDisplayContent.isDefaultDisplay && mLastFocusIsFullscreen != isFullscreen
+ && ((mLastAppearance ^ appearance) & APPEARANCE_LOW_PROFILE_BARS) != 0) {
+ mService.mInputManager.setSystemUiLightsOut(
+ isFullscreen || (appearance & APPEARANCE_LOW_PROFILE_BARS) != 0);
+ }
mLastDisableFlags = disableFlags;
mLastAppearance = appearance;
mLastFullscreenAppearance = fullscreenAppearance;
@@ -2802,10 +2736,6 @@ public class DisplayPolicy {
}
});
- if (mDisplayContent.isDefaultDisplay) {
- mService.mInputManager.setSystemUiLightsOut(
- isFullscreen || (appearance & APPEARANCE_LOW_PROFILE_BARS) != 0);
- }
return true;
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index 472678cf8e37..5d4dbc8388c4 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -19,6 +19,8 @@ package com.android.server.wm;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;
@@ -31,6 +33,7 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.IWindowManager;
import android.view.Surface;
+import android.view.WindowManager.DisplayImePolicy;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.DisplayContent.ForceScalingMode;
@@ -212,22 +215,23 @@ class DisplayWindowSettings {
mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
}
- boolean shouldShowImeLocked(DisplayContent dc) {
+ @DisplayImePolicy int getImePolicyLocked(DisplayContent dc) {
if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
// Default display should show IME.
- return true;
+ return DISPLAY_IME_POLICY_LOCAL;
}
final DisplayInfo displayInfo = dc.getDisplayInfo();
final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
- return settings.mShouldShowIme != null ? settings.mShouldShowIme : false;
+ return settings.mImePolicy != null ? settings.mImePolicy
+ : DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
}
- void setShouldShowImeLocked(DisplayContent dc, boolean shouldShow) {
+ void setDisplayImePolicy(DisplayContent dc, @DisplayImePolicy int imePolicy) {
final DisplayInfo displayInfo = dc.getDisplayInfo();
final SettingsProvider.SettingsEntry overrideSettings =
mSettingsProvider.getOverrideSettings(displayInfo);
- overrideSettings.mShouldShowIme = shouldShow;
+ overrideSettings.mImePolicy = imePolicy;
mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
}
@@ -343,7 +347,7 @@ class DisplayWindowSettings {
@Nullable
Boolean mShouldShowSystemDecors;
@Nullable
- Boolean mShouldShowIme;
+ Integer mImePolicy;
@Nullable
Integer mFixedToUserRotation;
@Nullable
@@ -406,8 +410,8 @@ class DisplayWindowSettings {
mShouldShowSystemDecors = other.mShouldShowSystemDecors;
changed = true;
}
- if (other.mShouldShowIme != mShouldShowIme) {
- mShouldShowIme = other.mShouldShowIme;
+ if (!Objects.equals(other.mImePolicy, mImePolicy)) {
+ mImePolicy = other.mImePolicy;
changed = true;
}
if (!Objects.equals(other.mFixedToUserRotation, mFixedToUserRotation)) {
@@ -481,9 +485,9 @@ class DisplayWindowSettings {
mShouldShowSystemDecors = delta.mShouldShowSystemDecors;
changed = true;
}
- if (delta.mShouldShowIme != null
- && delta.mShouldShowIme != mShouldShowIme) {
- mShouldShowIme = delta.mShouldShowIme;
+ if (delta.mImePolicy != null
+ && !Objects.equals(delta.mImePolicy, mImePolicy)) {
+ mImePolicy = delta.mImePolicy;
changed = true;
}
if (delta.mFixedToUserRotation != null
@@ -509,7 +513,7 @@ class DisplayWindowSettings {
&& mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED
&& mShouldShowWithInsecureKeyguard == null
&& mShouldShowSystemDecors == null
- && mShouldShowIme == null
+ && mImePolicy == null
&& mFixedToUserRotation == null
&& mIgnoreOrientationRequest == null;
}
@@ -530,7 +534,7 @@ class DisplayWindowSettings {
&& Objects.equals(mShouldShowWithInsecureKeyguard,
that.mShouldShowWithInsecureKeyguard)
&& Objects.equals(mShouldShowSystemDecors, that.mShouldShowSystemDecors)
- && Objects.equals(mShouldShowIme, that.mShouldShowIme)
+ && Objects.equals(mImePolicy, that.mImePolicy)
&& Objects.equals(mFixedToUserRotation, that.mFixedToUserRotation)
&& Objects.equals(mIgnoreOrientationRequest,
that.mIgnoreOrientationRequest);
@@ -540,7 +544,7 @@ class DisplayWindowSettings {
public int hashCode() {
return Objects.hash(mWindowingMode, mUserRotationMode, mUserRotation, mForcedWidth,
mForcedHeight, mForcedDensity, mForcedScalingMode, mRemoveContentMode,
- mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mShouldShowIme,
+ mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mImePolicy,
mFixedToUserRotation, mIgnoreOrientationRequest);
}
@@ -557,7 +561,7 @@ class DisplayWindowSettings {
+ ", mRemoveContentMode=" + mRemoveContentMode
+ ", mShouldShowWithInsecureKeyguard=" + mShouldShowWithInsecureKeyguard
+ ", mShouldShowSystemDecors=" + mShouldShowSystemDecors
- + ", mShouldShowIme=" + mShouldShowIme
+ + ", mShouldShowIme=" + mImePolicy
+ ", mFixedToUserRotation=" + mFixedToUserRotation
+ ", mIgnoreOrientationRequest=" + mIgnoreOrientationRequest
+ '}';
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
index 83da136e2005..78f1426348a7 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -16,7 +16,9 @@
package com.android.server.wm;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -35,13 +37,11 @@ import android.view.DisplayAddress;
import android.view.DisplayInfo;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.wm.DisplayWindowSettings.SettingsProvider;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileNotFoundException;
@@ -49,7 +49,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -390,8 +389,15 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
"shouldShowWithInsecureKeyguard", null /* defaultValue */);
settingsEntry.mShouldShowSystemDecors = getBooleanAttribute(parser,
"shouldShowSystemDecors", null /* defaultValue */);
- settingsEntry.mShouldShowIme = getBooleanAttribute(parser, "shouldShowIme",
+ final Boolean shouldShowIme = getBooleanAttribute(parser, "shouldShowIme",
null /* defaultValue */);
+ if (shouldShowIme != null) {
+ settingsEntry.mImePolicy = shouldShowIme ? DISPLAY_IME_POLICY_LOCAL
+ : DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+ } else {
+ settingsEntry.mImePolicy = getIntegerAttribute(parser, "imePolicy",
+ null /* defaultValue */);
+ }
settingsEntry.mFixedToUserRotation = getIntegerAttribute(parser, "fixedToUserRotation",
null /* defaultValue */);
settingsEntry.mIgnoreOrientationRequest = getBooleanAttribute(parser,
@@ -478,9 +484,8 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
out.attribute(null, "shouldShowSystemDecors",
settingsEntry.mShouldShowSystemDecors.toString());
}
- if (settingsEntry.mShouldShowIme != null) {
- out.attribute(null, "shouldShowIme",
- settingsEntry.mShouldShowIme.toString());
+ if (settingsEntry.mImePolicy != null) {
+ out.attributeInt(null, "imePolicy", settingsEntry.mImePolicy);
}
if (settingsEntry.mFixedToUserRotation != null) {
out.attribute(null, "fixedToUserRotation",
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index c3b6149482e2..ebd91a093326 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -206,9 +206,8 @@ class KeyguardController {
mAodShowing ? 1 : 0,
1 /* keyguardGoingAway */,
"keyguardGoingAway");
- mRootWindowContainer.getDefaultDisplay()
- .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
- convertTransitFlags(flags));
+ mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
+ TRANSIT_KEYGUARD_GOING_AWAY, convertTransitFlags(flags));
updateKeyguardSleepToken();
// Some stack visibility might change (e.g. docked stack)
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index f1ae921c87f5..b6b172eeae5b 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
@@ -73,9 +74,10 @@ class LaunchParamsController {
* @param source The {@link ActivityRecord} from which activity was started from.
* @param options The {@link ActivityOptions} specified for the activity.
* @param result The resulting params.
+ * @param request The optional request from the activity starter.
*/
- void calculate(Task task, WindowLayout layout, ActivityRecord activity,
- ActivityRecord source, ActivityOptions options, int phase, LaunchParams result) {
+ void calculate(Task task, WindowLayout layout, ActivityRecord activity, ActivityRecord source,
+ ActivityOptions options, int phase, LaunchParams result, @Nullable Request request) {
result.reset();
if (task != null || activity != null) {
@@ -91,7 +93,7 @@ class LaunchParamsController {
final LaunchParamsModifier modifier = mModifiers.get(i);
switch(modifier.onCalculate(task, layout, activity, source, options, phase, mTmpCurrent,
- mTmpResult)) {
+ mTmpResult, request)) {
case RESULT_SKIP:
// Do not apply any results when we are told to skip
continue;
@@ -128,7 +130,8 @@ class LaunchParamsController {
boolean layoutTask(Task task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options) {
- calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams);
+ calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams,
+ null /* request */);
// No changes, return.
if (mTmpParams.isEmpty()) {
@@ -305,15 +308,17 @@ class LaunchParamsController {
* launched should have this be non-null.
* @param source the Activity that launched a new task. Could be {@code null}.
* @param options {@link ActivityOptions} used to start the activity with.
- * @param phase the calculation phase, see {@link LaunchParamsModifier.Phase}
+ * @param phase the calculation phase, see {@link Phase}
* @param currentParams launching params after the process of last {@link
* LaunchParamsModifier}.
* @param outParams the result params to be set.
+ * @param request Optional data to give more context on the launch
* @return see {@link LaunchParamsModifier.Result}
*/
@Result
- int onCalculate(Task task, WindowLayout layout, ActivityRecord activity,
+ int onCalculate(@Nullable Task task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options, @Phase int phase,
- LaunchParams currentParams, LaunchParams outParams);
+ LaunchParams currentParams, LaunchParams outParams,
+ @Nullable Request request);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 6dc957c1d118..8b2fa52afd22 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -35,6 +35,7 @@ import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -99,23 +100,25 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
ActivityRecord source, ActivityOptions options, LaunchParams currentParams,
LaunchParams outParams) {
return onCalculate(task, layout, activity, source, options, PHASE_BOUNDS, currentParams,
- outParams);
+ outParams, null);
}
@Override
- public int onCalculate(Task task, ActivityInfo.WindowLayout layout,
- ActivityRecord activity, ActivityRecord source, ActivityOptions options,
- int phase, LaunchParams currentParams, LaunchParams outParams) {
+ public int onCalculate(@Nullable Task task, @NonNull ActivityInfo.WindowLayout layout,
+ @NonNull ActivityRecord activity, @Nullable ActivityRecord source,
+ ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams,
+ @Nullable Request request) {
initLogBuilder(task, activity);
final int result = calculate(task, layout, activity, source, options, phase, currentParams,
- outParams);
+ outParams, request);
outputLog();
return result;
}
- private int calculate(Task task, ActivityInfo.WindowLayout layout,
- ActivityRecord activity, ActivityRecord source, ActivityOptions options, int phase,
- LaunchParams currentParams, LaunchParams outParams) {
+ private int calculate(@Nullable Task task, @NonNull ActivityInfo.WindowLayout layout,
+ @NonNull ActivityRecord activity, @Nullable ActivityRecord source,
+ ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams,
+ @Nullable Request request) {
final ActivityRecord root;
if (task != null) {
root = task.getRootActivity() == null ? activity : task.getRootActivity();
@@ -138,7 +141,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
// STEP 1: Determine the display area to launch the activity/task.
final TaskDisplayArea taskDisplayArea = getPreferredLaunchTaskDisplayArea(task,
- options, source, currentParams);
+ options, source, currentParams, activity, request);
outParams.mPreferredTaskDisplayArea = taskDisplayArea;
// TODO(b/152116619): Update the usages of display to use taskDisplayArea below.
final DisplayContent display = taskDisplayArea.mDisplayContent;
@@ -298,7 +301,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
private TaskDisplayArea getPreferredLaunchTaskDisplayArea(@Nullable Task task,
- @Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams) {
+ @Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams,
+ @NonNull ActivityRecord activityRecord, @Nullable Request request) {
TaskDisplayArea taskDisplayArea = null;
final WindowContainerToken optionLaunchTaskDisplayAreaToken = options != null
@@ -369,7 +373,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
taskDisplayArea = currentParams.mPreferredTaskDisplayArea;
}
- // Fallback to default display if the device didn't declare support for multi-display
+ // Re-route to default display if the device didn't declare support for multi-display
if (taskDisplayArea != null && !mSupervisor.mService.mSupportsMultiDisplay
&& taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY) {
taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
@@ -377,7 +381,53 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
return (taskDisplayArea != null)
? taskDisplayArea
- : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
+ : getFallbackDisplayAreaForActivity(activityRecord, request);
+ }
+
+ /**
+ * Calculates the default {@link TaskDisplayArea} for a task. We attempt to put the activity
+ * within the same display area if possible. The strategy is to find the display in the
+ * following order:
+ *
+ * <ol>
+ * <li>The display area of the top activity from the launching process will be used</li>
+ * <li>The display area of the top activity from the real launching process will be used
+ * </li>
+ * <li>Default display area from the associated root window container.</li>
+ * </ol>
+ * @param activityRecord the activity being started
+ * @param request optional {@link Request} made to start the activity record
+ * @return {@link TaskDisplayArea} to house the task
+ */
+ private TaskDisplayArea getFallbackDisplayAreaForActivity(
+ @NonNull ActivityRecord activityRecord, @Nullable Request request) {
+
+ WindowProcessController controllerFromLaunchingRecord = mSupervisor.mService
+ .getProcessController(activityRecord.launchedFromPid,
+ activityRecord.launchedFromUid);
+ final TaskDisplayArea displayAreaForLaunchingRecord = controllerFromLaunchingRecord == null
+ ? null : controllerFromLaunchingRecord.getTopActivityDisplayArea();
+ if (displayAreaForLaunchingRecord != null) {
+ return displayAreaForLaunchingRecord;
+ }
+
+ WindowProcessController controllerFromProcess = mSupervisor.mService.getProcessController(
+ activityRecord.getProcessName(), activityRecord.getUid());
+ final TaskDisplayArea displayAreaForRecord = controllerFromProcess == null ? null
+ : controllerFromProcess.getTopActivityDisplayArea();
+ if (displayAreaForRecord != null) {
+ return displayAreaForRecord;
+ }
+
+ WindowProcessController controllerFromRequest = request == null ? null : mSupervisor
+ .mService.getProcessController(request.realCallingPid, request.realCallingUid);
+ final TaskDisplayArea displayAreaFromSourceProcess = controllerFromRequest == null ? null
+ : controllerFromRequest.getTopActivityDisplayArea();
+ if (displayAreaFromSourceProcess != null) {
+ return displayAreaFromSourceProcess;
+ }
+
+ return mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
}
private boolean canInheritWindowingModeFromSource(@NonNull DisplayContent display,
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 341694d8ecb2..0cdd055d4052 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -26,6 +26,7 @@ import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
@@ -46,7 +47,6 @@ import com.android.internal.protolog.common.ProtoLog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Set;
/**
* Represents a logical transition.
@@ -91,13 +91,24 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
private final BLASTSyncEngine mSyncEngine;
/**
+ * This is a leash to put animating surfaces into flatly without clipping/ordering issues. It
+ * is a child of all the targets' shared ancestor.
+ */
+ private SurfaceControl mRootLeash = null;
+
+ /**
* Contains change infos for both participants and all ancestors. We have to track ancestors
* because they are all promotion candidates and thus we need their start-states
* to be captured.
*/
final ArrayMap<WindowContainer, ChangeInfo> mChanges = new ArrayMap<>();
+ /** The collected participants in the transition. */
final ArraySet<WindowContainer> mParticipants = new ArraySet<>();
+
+ /** The final animation targets derived from participants after promotion. */
+ private ArraySet<WindowContainer> mTargets = null;
+
private @TransitionState int mState = STATE_COLLECTING;
private boolean mReadyCalled = false;
@@ -190,6 +201,42 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
if (mState < STATE_PLAYING) {
throw new IllegalStateException("Can't finish a non-playing transition " + mSyncId);
}
+ final Point tmpPos = new Point();
+ // usually only size 1
+ final ArraySet<DisplayContent> displays = new ArraySet<>();
+ // Immediately apply all surface reparents, don't wait for pending/sync/etc.
+ SurfaceControl.Transaction t = mController.mAtm.mWindowManager.mTransactionFactory.get();
+ for (int i = mTargets.size() - 1; i >= 0; --i) {
+ final WindowContainer target = mTargets.valueAt(i);
+ if (target.getParent() != null) {
+ // Ensure surfaceControls are re-parented back into the hierarchy.
+ t.reparent(target.getSurfaceControl(), target.getParent().getSurfaceControl());
+ target.getRelativePosition(tmpPos);
+ t.setPosition(target.getSurfaceControl(), tmpPos.x, tmpPos.y);
+ displays.add(target.getDisplayContent());
+ }
+ }
+ // Need to update layers on ALL displays (for now) since they were all paused while
+ // the animation played.
+ for (int i = displays.size() - 1; i >= 0; --i) {
+ if (displays.valueAt(i) == null) continue;
+ displays.valueAt(i).assignChildLayers(t);
+ }
+ // Also pro-actively hide going-invisible activity surfaces in same transaction to
+ // prevent flickers due to reparenting and animation z-order mismatch.
+ for (int i = mParticipants.size() - 1; i >= 0; --i) {
+ final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
+ if (ar == null || ar.mVisibleRequested || !ar.isVisible()) continue;
+ t.hide(ar.getSurfaceControl());
+ }
+ if (mRootLeash.isValid()) {
+ t.remove(mRootLeash);
+ }
+ mRootLeash = null;
+ t.apply();
+ t.close();
+
+ // Commit all going-invisible containers
for (int i = 0; i < mParticipants.size(); ++i) {
final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
if (ar == null || ar.mVisibleRequested) {
@@ -234,7 +281,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
mState = STATE_PLAYING;
mController.moveToPlaying(this);
- final TransitionInfo info = calculateTransitionInfo(mType, mParticipants, mChanges);
+
+ // Resolve the animating targets from the participants
+ mTargets = calculateTargets(mParticipants, mChanges);
+ final TransitionInfo info = calculateTransitionInfo(mType, mTargets, mChanges);
+ mRootLeash = info.getRootLeash();
handleNonAppWindowsInTransition(displayId, mType, mFlags);
@@ -245,11 +296,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
mController.getTransitionPlayer().onTransitionReady(this, info, transaction);
} catch (RemoteException e) {
// If there's an exception when trying to send the mergedTransaction to the
- // client, we should immediately apply it here so the transactions aren't lost.
+ // client, we should finish and apply it here so the transactions aren't lost.
transaction.apply();
+ finishTransition();
}
} else {
+ // No player registered, so just finish/apply immediately
transaction.apply();
+ finishTransition();
}
mSyncId = -1;
}
@@ -325,10 +379,12 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
*
* @return {@code true} if transition in target can be promoted to its parent.
*/
- private static boolean canPromote(
- WindowContainer target, ArraySet<WindowContainer> topTargets) {
+ private static boolean canPromote(WindowContainer target, ArraySet<WindowContainer> topTargets,
+ ArrayMap<WindowContainer, ChangeInfo> changes) {
final WindowContainer parent = target.getParent();
- if (parent == null || !parent.canCreateRemoteAnimationTarget()) {
+ final ChangeInfo parentChanges = parent != null ? changes.get(parent) : null;
+ if (parent == null || !parent.canCreateRemoteAnimationTarget()
+ || parentChanges == null || !parentChanges.hasChanged(parent)) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " SKIP: %s",
parent == null ? "no parent" : ("parent can't be target " + parent));
return false;
@@ -394,14 +450,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// Go through each target until we find one that can be promoted.
for (WindowContainer targ : topTargets) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " checking %s", targ);
- if (!canPromote(targ, topTargets)) {
+ if (!canPromote(targ, topTargets, changes)) {
continue;
}
- final WindowContainer parent = targ.getParent();
// No obstructions found to promotion, so promote
+ final WindowContainer parent = targ.getParent();
+ final ChangeInfo parentInfo = changes.get(parent);
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
" CAN PROMOTE: promoting to parent %s", parent);
- final ChangeInfo parentInfo = changes.get(parent);
targets.add(parent);
// Go through all children of newly-promoted container and remove them from the
@@ -443,10 +499,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
* animation targets to higher level in the window hierarchy if possible.
*/
@VisibleForTesting
- static TransitionInfo calculateTransitionInfo(int type, Set<WindowContainer> participants,
+ @NonNull
+ static ArraySet<WindowContainer> calculateTargets(ArraySet<WindowContainer> participants,
ArrayMap<WindowContainer, ChangeInfo> changes) {
- final TransitionInfo out = new TransitionInfo(type);
-
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
"Start calculating TransitionInfo based on participants: %s", participants);
@@ -470,6 +525,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// Search through ancestors to find the top-most participant (if one exists)
WindowContainer topParent = null;
tmpList.clear();
+ if (reportIfNotTop(wc)) {
+ tmpList.add(wc);
+ }
for (WindowContainer p = wc.getParent(); p != null; p = p.getParent()) {
if (participants.contains(p)) {
topParent = p;
@@ -479,8 +537,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
}
}
if (topParent != null) {
- // There was an ancestor participant, so don't add wc to targets. However, continue
- // to add any always-report parents along the way.
+ // There was an ancestor participant, so don't add wc to targets unless always-
+ // report. Similarly, add any always-report parents along the way.
for (int i = 0; i < tmpList.size(); ++i) {
targets.add(tmpList.get(i));
final ChangeInfo info = changes.get(tmpList.get(i));
@@ -508,10 +566,70 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
while (tryPromote(topTargets, targets, changes)) {
// Empty on purpose
}
+ return targets;
+ }
- // Convert all the resolved ChangeInfos into a TransactionInfo object.
- for (int i = targets.size() - 1; i >= 0; --i) {
- final WindowContainer target = targets.valueAt(i);
+ /** Add any of `members` within `root` to `out` in top-to-bottom z-order. */
+ private static void addMembersInOrder(WindowContainer root, ArraySet<WindowContainer> members,
+ ArrayList<WindowContainer> out) {
+ for (int i = root.getChildCount() - 1; i >= 0; --i) {
+ final WindowContainer child = root.getChildAt(i);
+ addMembersInOrder(child, members, out);
+ if (members.contains(child)) {
+ out.add(child);
+ }
+ }
+ }
+
+ /**
+ * Construct a TransitionInfo object from a set of targets and changes. Also populates the
+ * root surface.
+ */
+ @VisibleForTesting
+ @NonNull
+ static TransitionInfo calculateTransitionInfo(int type, ArraySet<WindowContainer> targets,
+ ArrayMap<WindowContainer, ChangeInfo> changes) {
+ final TransitionInfo out = new TransitionInfo(type);
+ if (targets.isEmpty()) {
+ out.setRootLeash(new SurfaceControl(), 0, 0);
+ return out;
+ }
+
+ // Find the top-most shared ancestor
+ WindowContainer ancestor = targets.valueAt(0).getParent();
+ // Go up ancestor parent chain until all topTargets are descendants.
+ ancestorLoop:
+ while (ancestor != null) {
+ for (int i = 1; i < targets.size(); ++i) {
+ if (!targets.valueAt(i).isDescendantOf(ancestor)) {
+ ancestor = ancestor.getParent();
+ continue ancestorLoop;
+ }
+ }
+ break;
+ }
+
+ // Sort targets top-to-bottom in Z.
+ ArrayList<WindowContainer> sortedTargets = new ArrayList<>();
+ addMembersInOrder(ancestor, targets, sortedTargets);
+
+ // make leash based on highest (z-order) direct child of ancestor with a participant.
+ WindowContainer leashReference = sortedTargets.get(0);
+ while (leashReference.getParent() != ancestor) {
+ leashReference = leashReference.getParent();
+ }
+ final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName(
+ "Transition Root: " + leashReference.getName()).build();
+ SurfaceControl.Transaction t = ancestor.mWmService.mTransactionFactory.get();
+ t.setLayer(rootLeash, leashReference.getLastLayer());
+ t.apply();
+ t.close();
+ out.setRootLeash(rootLeash, ancestor.getBounds().left, ancestor.getBounds().top);
+
+ // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order.
+ final int count = sortedTargets.size();
+ for (int i = 0; i < count; ++i) {
+ final WindowContainer target = sortedTargets.get(i);
final ChangeInfo info = changes.get(target);
final TransitionInfo.Change change = new TransitionInfo.Change(
target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken()
@@ -520,8 +638,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
change.setParent(info.mParent.mRemoteToken.toWindowContainerToken());
}
change.setMode(info.getTransitMode(target));
- change.setStartBounds(info.mAbsoluteBounds);
- change.setEndBounds(target.getBounds());
+ change.setStartAbsBounds(info.mAbsoluteBounds);
+ change.setEndAbsBounds(target.getBounds());
+ change.setEndRelOffset(target.getBounds().left - target.getParent().getBounds().left,
+ target.getBounds().top - target.getParent().getBounds().top);
out.addChange(change);
}
@@ -543,23 +663,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// before change state
boolean mVisible;
int mWindowingMode;
- Rect mAbsoluteBounds;
+ final Rect mAbsoluteBounds = new Rect();
ChangeInfo(@NonNull WindowContainer origState) {
mVisible = origState.isVisibleRequested();
mWindowingMode = origState.getWindowingMode();
- mAbsoluteBounds = origState.getBounds();
+ mAbsoluteBounds.set(origState.getBounds());
}
@VisibleForTesting
ChangeInfo(boolean visible, boolean existChange) {
mVisible = visible;
- mAbsoluteBounds = new Rect();
mExistenceChanged = existChange;
}
boolean hasChanged(@NonNull WindowContainer newState) {
- return newState.isVisibleRequested() != mVisible
+ // If it's invisible and hasn't changed visibility, always return false since even if
+ // something changed, it wouldn't be a visible change.
+ final boolean currVisible = newState.isVisibleRequested();
+ if (currVisible == mVisible && !mVisible) return false;
+ return currVisible != mVisible
// if mWindowingMode is 0, this container wasn't attached at collect time, so
// assume no change in windowing-mode.
|| (mWindowingMode != 0 && newState.getWindowingMode() != mWindowingMode)
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 890ae8f2a434..2f5d10afe3da 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -109,10 +109,18 @@ class TransitionController {
return mCollectingTransition != null;
}
+ /**
+ * @return {@code true} if transition is actively playing. This is not necessarily {@code true}
+ * during collection.
+ */
+ boolean isPlaying() {
+ return !mPlayingTransitions.isEmpty();
+ }
+
/** @return {@code true} if a transition is running */
boolean inTransition() {
// TODO(shell-transitions): eventually properly support multiple
- return mCollectingTransition != null || !mPlayingTransitions.isEmpty();
+ return isCollecting() || isPlaying();
}
/** @return {@code true} if wc is in a participant subtree */
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 06449c69f1be..a1bb89d26f2f 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2089,6 +2089,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
void assignLayer(Transaction t, int layer) {
+ // Don't assign layers while a transition animation is playing
+ // TODO(b/173528115): establish robust best-practices around z-order fighting.
+ if (mWmService.mAtmService.getTransitionController().isPlaying()) return;
final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
if (mSurfaceControl != null && changed) {
setLayer(t, layer);
@@ -2113,6 +2116,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
mSurfaceAnimator.setLayer(t, layer);
}
+ int getLastLayer() {
+ return mLastLayer;
+ }
+
protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
// Route through surface animator to accommodate that our surface control might be
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index d082778f50ba..a3a9eb773abf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -30,6 +30,7 @@ import android.view.IWindow;
import android.view.InputChannel;
import android.view.MagnificationSpec;
import android.view.WindowInfo;
+import android.view.WindowManager.DisplayImePolicy;
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.server.input.InputManagerService;
@@ -506,12 +507,12 @@ public abstract class WindowManagerInternal {
public abstract boolean shouldShowSystemDecorOnDisplay(int displayId);
/**
- * Indicates that the display should show IME.
+ * Indicates the policy for how the display should show IME.
*
* @param displayId The id of the display.
- * @return {@code true} if the display should show IME when an input field become focused on it.
+ * @return The policy for how the display should show IME.
*/
- public abstract boolean shouldShowIme(int displayId);
+ public abstract @DisplayImePolicy int getDisplayImePolicy(int displayId);
/**
* Show IME on imeTargetWindow once IME has finished layout.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 580c088ec133..d62df85e3cc0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -48,6 +48,7 @@ import static android.provider.Settings.Global.DEVELOPMENT_IGNORE_VENDOR_DISPLAY
import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -255,6 +256,7 @@ import android.view.View;
import android.view.WindowContentFrameStats;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.RemoveContentMode;
import android.view.WindowManagerGlobal;
@@ -1625,7 +1627,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
- displayPolicy.adjustWindowParamsLw(win, win.mAttrs, callingPid, callingUid);
+ displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
win.updateRequestedVisibility(requestedVisibility);
res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
@@ -2195,7 +2197,7 @@ public class WindowManagerService extends IWindowManager.Stub
int flagChanges = 0;
int privateFlagChanges = 0;
if (attrs != null) {
- displayPolicy.adjustWindowParamsLw(win, attrs, pid, uid);
+ displayPolicy.adjustWindowParamsLw(win, attrs);
win.mToken.adjustWindowParams(win, attrs);
int disableFlags =
(attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK;
@@ -7245,28 +7247,25 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public boolean shouldShowIme(int displayId) {
- if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowIme()")) {
+ public @DisplayImePolicy int getDisplayImePolicy(int displayId) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getDisplayImePolicy()")) {
throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
}
- boolean show;
final DisplayContent dc = mRoot.getDisplayContent(displayId);
if (dc == null) {
ProtoLog.w(WM_ERROR,
- "Attempted to get IME flag of a display that does not exist: %d",
+ "Attempted to get IME policy of a display that does not exist: %d",
displayId);
- return false;
+ return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
}
synchronized (mGlobalLock) {
- show = dc.canShowIme();
+ return dc.getImePolicy();
}
-
- return show;
}
@Override
- public void setShouldShowIme(int displayId, boolean shouldShow) {
- if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowIme()")) {
+ public void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setDisplayImePolicy()")) {
throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
}
final long origId = Binder.clearCallingIdentity();
@@ -7274,16 +7273,16 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
if (displayContent == null) {
- ProtoLog.w(WM_ERROR, "Attempted to set IME flag to a display that does not "
- + "exist: %d", displayId);
+ ProtoLog.w(WM_ERROR, "Attempted to set IME policy to a display"
+ + " that does not exist: %d", displayId);
return;
}
if (!displayContent.isTrusted()) {
- throw new SecurityException("Attempted to set IME flag to an untrusted "
+ throw new SecurityException("Attempted to set IME policy to an untrusted "
+ "virtual display: " + displayId);
}
- mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow);
+ mDisplayWindowSettings.setDisplayImePolicy(displayContent, imePolicy);
displayContent.reconfigureDisplayLocked();
}
@@ -7765,9 +7764,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public boolean shouldShowIme(int displayId) {
+ public @DisplayImePolicy int getDisplayImePolicy(int displayId) {
synchronized (mGlobalLock) {
- return WindowManagerService.this.shouldShowIme(displayId);
+ return WindowManagerService.this.getDisplayImePolicy(displayId);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index c55f059cae16..8f8fea34e620 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -730,6 +730,28 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return mHasActivities || mHasRecentTasks;
}
+ @Nullable
+ TaskDisplayArea getTopActivityDisplayArea() {
+ if (mActivities.isEmpty()) {
+ return null;
+ }
+
+ final int lastIndex = mActivities.size() - 1;
+ ActivityRecord topRecord = mActivities.get(lastIndex);
+ TaskDisplayArea displayArea = topRecord.getDisplayArea();
+
+ for (int index = lastIndex - 1; index >= 0; --index) {
+ ActivityRecord nextRecord = mActivities.get(index);
+ TaskDisplayArea nextDisplayArea = nextRecord.getDisplayArea();
+ if (nextRecord.compareTo(topRecord) > 0 && nextDisplayArea != null) {
+ topRecord = nextRecord;
+ displayArea = nextDisplayArea;
+ }
+ }
+
+ return displayArea;
+ }
+
private boolean hasActivityInVisibleTask() {
for (int i = mActivities.size() - 1; i >= 0; --i) {
Task task = mActivities.get(i).getTask();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e99c7f92a890..c318fad4d0a0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5271,6 +5271,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mSurfaceControl == null) {
return;
}
+ if (mWmService.mWindowPlacerLocked.isLayoutDeferred() || isGoneForLayout()) {
+ // Since this relies on mWindowFrames, changes made while layout is deferred are
+ // likely to be invalid. Similarly, if it's goneForLayout, mWindowFrames may not be
+ // up-to-date and thus can't be relied on.
+ return;
+ }
transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
mSurfacePosition);
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index da2c005d7332..6da9517743d2 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -53,8 +53,8 @@ cc_library_static {
"com_android_server_UsbDescriptorParser.cpp",
"com_android_server_UsbMidiDevice.cpp",
"com_android_server_UsbHostManager.cpp",
+ "com_android_server_vibrator_VibratorController.cpp",
"com_android_server_VibratorManagerService.cpp",
- "com_android_server_VibratorService.cpp",
"com_android_server_PersistentDataBlockService.cpp",
"com_android_server_am_CachedAppOptimizer.cpp",
"com_android_server_am_LowMemDetector.cpp",
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index 4c017f5513a2..6f74885b98e5 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -2,8 +2,8 @@
per-file com_android_server_lights_LightsService.cpp = michaelwr@google.com, santoscordon@google.com
# Haptics
+per-file com_android_server_vibrator_VibratorController.cpp = michaelwr@google.com
per-file com_android_server_VibratorManagerService.cpp = michaelwr@google.com
-per-file com_android_server_VibratorService.cpp = michaelwr@google.com
# Input
per-file com_android_server_input_InputManagerService.cpp = michaelwr@google.com, svv@google.com
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index 9aca84849fc6..afce5379febb 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,18 @@
* limitations under the License.
*/
-#define LOG_TAG "VibratorService"
+#define LOG_TAG "VibratorController"
#include <android/hardware/vibrator/1.3/IVibrator.h>
#include <android/hardware/vibrator/IVibrator.h>
-#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include "core_jni_helpers.h"
+#include "jni.h"
-#include <utils/misc.h>
#include <utils/Log.h>
-
-#include <inttypes.h>
+#include <utils/misc.h>
#include <vibratorservice/VibratorHalController.h>
@@ -48,58 +46,59 @@ static struct {
} sPrimitiveClassInfo;
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
- static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
+ static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
- static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
+ static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
- static_cast<uint8_t>(aidl::EffectStrength::STRONG));
+ static_cast<uint8_t>(aidl::EffectStrength::STRONG));
static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
- static_cast<uint8_t>(aidl::Effect::CLICK));
+ static_cast<uint8_t>(aidl::Effect::CLICK));
static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
- static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
-static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) ==
- static_cast<uint8_t>(aidl::Effect::TICK));
-static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) ==
- static_cast<uint8_t>(aidl::Effect::THUD));
-static_assert(static_cast<uint8_t>(V1_3::Effect::POP) ==
- static_cast<uint8_t>(aidl::Effect::POP));
+ static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(aidl::Effect::TICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(aidl::Effect::THUD));
+static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(aidl::Effect::POP));
static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
- static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
+ static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
+ static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
+ static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
- static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
+ static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
- static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
+ static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
-class NativeVibratorService {
+class VibratorControllerWrapper {
public:
- NativeVibratorService(JNIEnv* env, jobject callbackListener)
- : mController(std::make_unique<vibrator::HalController>()),
+ VibratorControllerWrapper(JNIEnv* env, int32_t vibratorId, jobject callbackListener)
+ // TODO(b/167946816): use ManagerHalController to get vibrator by id
+ : mHal(std::make_unique<vibrator::HalController>()),
+ mVibratorId(vibratorId),
mCallbackListener(env->NewGlobalRef(callbackListener)) {
LOG_ALWAYS_FATAL_IF(mCallbackListener == nullptr,
"Unable to create global reference to vibration callback handler");
}
- ~NativeVibratorService() {
+ ~VibratorControllerWrapper() {
auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
jniEnv->DeleteGlobalRef(mCallbackListener);
}
- vibrator::HalController* controller() const { return mController.get(); }
+ vibrator::HalController* hal() const { return mHal.get(); }
std::function<void()> createCallback(jlong vibrationId) {
return [vibrationId, this]() {
auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
- jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, vibrationId);
+ jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, mVibratorId,
+ vibrationId);
};
}
private:
- const std::unique_ptr<vibrator::HalController> mController;
+ const std::unique_ptr<vibrator::HalController> mHal;
+ const int32_t mVibratorId;
const jobject mCallbackListener;
};
@@ -112,80 +111,80 @@ static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primit
return effect;
}
-static void destroyNativeService(void* servicePtr) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service) {
- delete service;
+static void destroyNativeWrapper(void* ptr) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper) {
+ delete wrapper;
}
}
-static jlong vibratorInit(JNIEnv* env, jclass /* clazz */, jobject callbackListener) {
- std::unique_ptr<NativeVibratorService> service =
- std::make_unique<NativeVibratorService>(env, callbackListener);
- service->controller()->init();
- return reinterpret_cast<jlong>(service.release());
+static jlong vibratorInit(JNIEnv* env, jclass /* clazz */, jint vibratorId,
+ jobject callbackListener) {
+ std::unique_ptr<VibratorControllerWrapper> wrapper =
+ std::make_unique<VibratorControllerWrapper>(env, vibratorId, callbackListener);
+ wrapper->hal()->init();
+ return reinterpret_cast<jlong>(wrapper.release());
}
static jlong vibratorGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) {
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeService));
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeWrapper));
}
-static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorExists failed because native service was not initialized");
+static jboolean vibratorIsAvailable(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorIsAvailable failed because native wrapper was not initialized");
return JNI_FALSE;
}
- return service->controller()->ping().isOk() ? JNI_TRUE : JNI_FALSE;
+ return wrapper->hal()->ping().isOk() ? JNI_TRUE : JNI_FALSE;
}
-static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong timeoutMs,
+static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong timeoutMs,
jlong vibrationId) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorOn failed because native service was not initialized");
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorOn failed because native wrapper was not initialized");
return;
}
- auto callback = service->createCallback(vibrationId);
- service->controller()->on(std::chrono::milliseconds(timeoutMs), callback);
+ auto callback = wrapper->createCallback(vibrationId);
+ wrapper->hal()->on(std::chrono::milliseconds(timeoutMs), callback);
}
-static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorOff failed because native service was not initialized");
+static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorOff failed because native wrapper was not initialized");
return;
}
- service->controller()->off();
+ wrapper->hal()->off();
}
-static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
- jint amplitude) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorSetAmplitude failed because native service was not initialized");
+static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong ptr, jint amplitude) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorSetAmplitude failed because native wrapper was not initialized");
return;
}
- service->controller()->setAmplitude(static_cast<int32_t>(amplitude));
+ wrapper->hal()->setAmplitude(static_cast<int32_t>(amplitude));
}
-static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
+static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong ptr,
jboolean enabled) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorSetExternalControl failed because native service was not initialized");
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorSetExternalControl failed because native wrapper was not initialized");
return;
}
- service->controller()->setExternalControl(enabled);
+ wrapper->hal()->setExternalControl(enabled);
}
-static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorGetSupportedEffects failed because native service was not initialized");
+static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorGetSupportedEffects failed because native wrapper was not initialized");
return nullptr;
}
- auto result = service->controller()->getSupportedEffects();
+ auto result = wrapper->hal()->getSupportedEffects();
if (!result.isOk()) {
return nullptr;
}
@@ -196,13 +195,13 @@ static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jl
return effects;
}
-static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorGetSupportedPrimitives failed because native service was not initialized");
+static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorGetSupportedPrimitives failed because native wrapper was not initialized");
return nullptr;
}
- auto result = service->controller()->getSupportedPrimitives();
+ auto result = wrapper->hal()->getSupportedPrimitives();
if (!result.isOk()) {
return nullptr;
}
@@ -213,25 +212,25 @@ static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */,
return primitives;
}
-static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong effect,
+static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong effect,
jlong strength, jlong vibrationId) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorPerformEffect failed because native service was not initialized");
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorPerformEffect failed because native wrapper was not initialized");
return -1;
}
aidl::Effect effectType = static_cast<aidl::Effect>(effect);
aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength);
- auto callback = service->createCallback(vibrationId);
- auto result = service->controller()->performEffect(effectType, effectStrength, callback);
+ auto callback = wrapper->createCallback(vibrationId);
+ auto result = wrapper->hal()->performEffect(effectType, effectStrength, callback);
return result.isOk() ? result.value().count() : -1;
}
-static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
+static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong ptr,
jobjectArray composition, jlong vibrationId) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorPerformComposedEffect failed because native service was not initialized");
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorPerformComposedEffect failed because native wrapper was not initialized");
return;
}
size_t size = env->GetArrayLength(composition);
@@ -240,46 +239,46 @@ static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong
jobject element = env->GetObjectArrayElement(composition, i);
effects.push_back(effectFromJavaPrimitive(env, element));
}
- auto callback = service->createCallback(vibrationId);
- service->controller()->performComposedEffect(effects, callback);
+ auto callback = wrapper->createCallback(vibrationId);
+ wrapper->hal()->performComposedEffect(effects, callback);
}
-static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorGetCapabilities failed because native service was not initialized");
+static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorGetCapabilities failed because native wrapper was not initialized");
return 0;
}
- auto result = service->controller()->getCapabilities();
+ auto result = wrapper->hal()->getCapabilities();
return result.isOk() ? static_cast<jlong>(result.value()) : 0;
}
-static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong id,
+static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id,
jlong effect, jlong strength) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorAlwaysOnEnable failed because native service was not initialized");
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorAlwaysOnEnable failed because native wrapper was not initialized");
return;
}
- service->controller()->alwaysOnEnable(static_cast<int32_t>(id),
- static_cast<aidl::Effect>(effect),
- static_cast<aidl::EffectStrength>(strength));
+ wrapper->hal()->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
+ static_cast<aidl::EffectStrength>(strength));
}
-static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong id) {
- NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr);
- if (service == nullptr) {
- ALOGE("vibratorAlwaysOnDisable failed because native service was not initialized");
+static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id) {
+ VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
+ if (wrapper == nullptr) {
+ ALOGE("vibratorAlwaysOnDisable failed because native wrapper was not initialized");
return;
}
- service->controller()->alwaysOnDisable(static_cast<int32_t>(id));
+ wrapper->hal()->alwaysOnDisable(static_cast<int32_t>(id));
}
static const JNINativeMethod method_table[] = {
- {"vibratorInit", "(Lcom/android/server/VibratorService$OnCompleteListener;)J",
+ {"vibratorInit",
+ "(ILcom/android/server/vibrator/VibratorController$OnVibrationCompleteListener;)J",
(void*)vibratorInit},
{"vibratorGetFinalizer", "()J", (void*)vibratorGetFinalizer},
- {"vibratorExists", "(J)Z", (void*)vibratorExists},
+ {"vibratorIsAvailable", "(J)Z", (void*)vibratorIsAvailable},
{"vibratorOn", "(JJJ)V", (void*)vibratorOn},
{"vibratorOff", "(J)V", (void*)vibratorOff},
{"vibratorSetAmplitude", "(JI)V", (void*)vibratorSetAmplitude},
@@ -295,11 +294,12 @@ static const JNINativeMethod method_table[] = {
{"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable},
};
-int register_android_server_VibratorService(JavaVM* jvm, JNIEnv* env) {
+int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env) {
sJvm = jvm;
- jclass listenerClass =
- FindClassOrDie(env, "com/android/server/VibratorService$OnCompleteListener");
- sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(J)V");
+ auto listenerClassName =
+ "com/android/server/vibrator/VibratorController$OnVibrationCompleteListener";
+ jclass listenerClass = FindClassOrDie(env, listenerClassName);
+ sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(IJ)V");
jclass primitiveClass =
FindClassOrDie(env, "android/os/VibrationEffect$Composition$PrimitiveEffect");
@@ -307,8 +307,8 @@ int register_android_server_VibratorService(JavaVM* jvm, JNIEnv* env) {
sPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F");
sPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I");
- return jniRegisterNativeMethods(env, "com/android/server/VibratorService", method_table,
- NELEM(method_table));
+ return jniRegisterNativeMethods(env, "com/android/server/vibrator/VibratorController",
+ method_table, NELEM(method_table));
}
}; // namespace android
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 79b5fed3e448..5a0d08aeb6b3 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -37,8 +37,8 @@ int register_android_server_UsbDeviceManager(JNIEnv* env);
int register_android_server_UsbMidiDevice(JNIEnv* env);
int register_android_server_UsbHostManager(JNIEnv* env);
int register_android_server_vr_VrManagerService(JNIEnv* env);
+int register_android_server_vibrator_VibratorController(JavaVM* vm, JNIEnv* env);
int register_android_server_VibratorManagerService(JNIEnv* env);
-int register_android_server_VibratorService(JavaVM* vm, JNIEnv* env);
int register_android_server_location_GnssLocationProvider(JNIEnv* env);
int register_android_server_connectivity_Vpn(JNIEnv* env);
int register_android_server_TestNetworkService(JNIEnv* env);
@@ -90,8 +90,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_UsbAlsaJackDetector(env);
register_android_server_UsbHostManager(env);
register_android_server_vr_VrManagerService(env);
+ register_android_server_vibrator_VibratorController(vm, env);
register_android_server_VibratorManagerService(env);
- register_android_server_VibratorService(vm, env);
register_android_server_SystemServer(env);
register_android_server_location_GnssLocationProvider(env);
register_android_server_connectivity_Vpn(env);
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 9c8f733730a7..f375421043fd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -16,6 +16,7 @@
package com.android.server;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyLong;
@@ -44,6 +45,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.util.ArraySet;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
@@ -63,6 +65,7 @@ import org.mockito.stubbing.Answer;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
/**
@@ -79,9 +82,11 @@ public class RescuePartyTest {
private static final String PROP_DISABLE_RESCUE = "persist.sys.disable_rescue";
private static final String CALLING_PACKAGE1 = "com.package.name1";
private static final String CALLING_PACKAGE2 = "com.package.name2";
+ private static final String CALLING_PACKAGE3 = "com.package.name3";
private static final String NAMESPACE1 = "namespace1";
private static final String NAMESPACE2 = "namespace2";
private static final String NAMESPACE3 = "namespace3";
+ private static final String NAMESPACE4 = "namespace4";
private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG =
"persist.device_config.configuration.disable_rescue_party";
private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
@@ -89,6 +94,8 @@ public class RescuePartyTest {
private MockitoSession mSession;
private HashMap<String, String> mSystemSettingsMap;
+ //Records the namespaces wiped by setProperties().
+ private HashSet<String> mNamespacesWiped;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mMockContext;
@@ -119,6 +126,7 @@ public class RescuePartyTest {
.spyStatic(PackageWatchdog.class)
.startMocking();
mSystemSettingsMap = new HashMap<>();
+ mNamespacesWiped = new HashSet<>();
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
// Reset observer instance to get new mock context on every run
@@ -167,6 +175,16 @@ public class RescuePartyTest {
anyBoolean()));
doAnswer((Answer<Void>) invocationOnMock -> null)
.when(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()));
+ doAnswer((Answer<Boolean>) invocationOnMock -> {
+ DeviceConfig.Properties properties = invocationOnMock.getArgument(0);
+ String namespace = properties.getNamespace();
+ // record a wipe
+ if (properties.getKeyset().isEmpty()) {
+ mNamespacesWiped.add(namespace);
+ }
+ return true;
+ }
+ ).when(() -> DeviceConfig.setProperties(any(DeviceConfig.Properties.class)));
// Mock PackageWatchdog
doAnswer((Answer<PackageWatchdog>) invocationOnMock -> mMockPackageWatchdog)
@@ -450,6 +468,122 @@ public class RescuePartyTest {
assertEquals(observer.onBootLoop(5), PackageHealthObserverImpact.USER_IMPACT_HIGH);
}
+ @Test
+ public void testResetDeviceConfigForPackagesOnlyRuntimeMap() {
+ RescueParty.onSettingsProviderPublished(mMockContext);
+ verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
+ mMonitorCallbackCaptor.capture()));
+
+ // Record DeviceConfig accesses
+ RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+ RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue();
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3));
+ // Fake DeviceConfig value changes
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3));
+
+ doReturn("").when(() -> DeviceConfig.getString(
+ eq(RescueParty.NAMESPACE_CONFIGURATION),
+ eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
+ eq("")));
+
+ RescueParty.resetDeviceConfigForPackages(Arrays.asList(new String[]{CALLING_PACKAGE1}));
+ ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
+ Arrays.asList(new String[]{NAMESPACE1, NAMESPACE2}));
+ assertEquals(mNamespacesWiped, expectedNamespacesWiped);
+ }
+
+ @Test
+ public void testResetDeviceConfigForPackagesOnlyPresetMap() {
+ RescueParty.onSettingsProviderPublished(mMockContext);
+ verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
+ mMonitorCallbackCaptor.capture()));
+
+ String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + ","
+ + NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
+ + NAMESPACE3 + ":" + CALLING_PACKAGE1;
+ doReturn(presetMapping).when(() -> DeviceConfig.getString(
+ eq(RescueParty.NAMESPACE_CONFIGURATION),
+ eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
+ eq("")));
+
+ RescueParty.resetDeviceConfigForPackages(Arrays.asList(new String[]{CALLING_PACKAGE1}));
+ ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
+ Arrays.asList(new String[]{NAMESPACE1, NAMESPACE3}));
+ assertEquals(mNamespacesWiped, expectedNamespacesWiped);
+ }
+
+ @Test
+ public void testResetDeviceConfigForPackagesBothMaps() {
+ RescueParty.onSettingsProviderPublished(mMockContext);
+ verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
+ mMonitorCallbackCaptor.capture()));
+
+ // Record DeviceConfig accesses
+ RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+ RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue();
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE3, NAMESPACE4));
+ // Fake DeviceConfig value changes
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE4));
+
+ String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + ","
+ + NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
+ + NAMESPACE4 + ":" + CALLING_PACKAGE3;
+ doReturn(presetMapping).when(() -> DeviceConfig.getString(
+ eq(RescueParty.NAMESPACE_CONFIGURATION),
+ eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
+ eq("")));
+
+ RescueParty.resetDeviceConfigForPackages(
+ Arrays.asList(new String[]{CALLING_PACKAGE1, CALLING_PACKAGE2}));
+ ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
+ Arrays.asList(new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3}));
+ assertEquals(mNamespacesWiped, expectedNamespacesWiped);
+ }
+
+ @Test
+ public void testResetDeviceConfigNoExceptionWhenFlagMalformed() {
+ RescueParty.onSettingsProviderPublished(mMockContext);
+ verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
+ mMonitorCallbackCaptor.capture()));
+
+ // Record DeviceConfig accesses
+ RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+ RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue();
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE3, NAMESPACE4));
+ // Fake DeviceConfig value changes
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE4));
+
+ String invalidPresetMapping = NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
+ + NAMESPACE1 + "." + CALLING_PACKAGE2;
+ doReturn(invalidPresetMapping).when(() -> DeviceConfig.getString(
+ eq(RescueParty.NAMESPACE_CONFIGURATION),
+ eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
+ eq("")));
+
+ RescueParty.resetDeviceConfigForPackages(
+ Arrays.asList(new String[]{CALLING_PACKAGE1, CALLING_PACKAGE2}));
+ ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
+ Arrays.asList(new String[]{NAMESPACE1, NAMESPACE3}));
+ assertEquals(mNamespacesWiped, expectedNamespacesWiped);
+ }
+
private void verifySettingsResets(int resetMode, String[] resetNamespaces,
HashMap<String, Integer> configResetVerifiedTimesMap) {
verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
diff --git a/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java b/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java
index 9efb38a75f35..84b886eb4b3d 100644
--- a/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java
+++ b/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java
@@ -29,7 +29,7 @@ import java.util.List;
public class LocationTimeZoneEventTest {
- private static final long ARBITRARY_ELAPSED_REALTIME_NANOS = 9999;
+ private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 9999;
private static final List<String> ARBITRARY_TIME_ZONE_IDS = singletonList("Europe/London");
@@ -42,7 +42,7 @@ public class LocationTimeZoneEventTest {
public void testBuildUnsetEventType() {
new LocationTimeZoneEvent.Builder()
.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS)
- .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS)
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
.build();
}
@@ -51,7 +51,7 @@ public class LocationTimeZoneEventTest {
new LocationTimeZoneEvent.Builder()
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS)
- .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS)
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
.build();
}
@@ -59,7 +59,7 @@ public class LocationTimeZoneEventTest {
public void testEquals() {
LocationTimeZoneEvent.Builder builder1 = new LocationTimeZoneEvent.Builder()
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
- .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS);
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
{
LocationTimeZoneEvent one = builder1.build();
assertEquals(one, one);
@@ -67,7 +67,7 @@ public class LocationTimeZoneEventTest {
LocationTimeZoneEvent.Builder builder2 = new LocationTimeZoneEvent.Builder()
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
- .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS);
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
{
LocationTimeZoneEvent one = builder1.build();
LocationTimeZoneEvent two = builder2.build();
@@ -75,7 +75,7 @@ public class LocationTimeZoneEventTest {
assertEquals(two, one);
}
- builder1.setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS + 1);
+ builder1.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1);
{
LocationTimeZoneEvent one = builder1.build();
LocationTimeZoneEvent two = builder2.build();
@@ -83,7 +83,7 @@ public class LocationTimeZoneEventTest {
assertNotEquals(two, one);
}
- builder2.setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS + 1);
+ builder2.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1);
{
LocationTimeZoneEvent one = builder1.build();
LocationTimeZoneEvent two = builder2.build();
@@ -128,7 +128,7 @@ public class LocationTimeZoneEventTest {
public void testParcelable() {
LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder()
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE)
- .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS);
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
assertRoundTripParcelable(builder.build());
builder.setEventType(LocationTimeZoneEvent.EVENT_TYPE_SUCCESS)
diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
index 6152421db659..64f31358ccb3 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
@@ -43,6 +43,8 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManagerInternal;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
import android.hardware.vibrator.IVibrator;
import android.media.AudioAttributes;
import android.media.AudioManager;
@@ -63,11 +65,13 @@ import android.os.Vibrator;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
+import android.view.InputDevice;
import androidx.test.InstrumentationRegistry;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.server.vibrator.VibratorController;
import org.junit.After;
import org.junit.Before;
@@ -118,8 +122,9 @@ public class VibratorServiceTest {
// TODO(b/131311651): replace with a FakeVibrator instead.
@Mock private Vibrator mVibratorMock;
@Mock private AppOpsManager mAppOpsManagerMock;
- @Mock private VibratorService.NativeWrapper mNativeWrapperMock;
+ @Mock private VibratorController.NativeWrapper mNativeWrapperMock;
@Mock private IVibratorStateListener mVibratorStateListenerMock;
+ @Mock private IInputManager mIInputManagerMock;
@Mock private IBinder mVibratorStateListenerBinderMock;
private TestLooper mTestLooper;
@@ -129,10 +134,12 @@ public class VibratorServiceTest {
public void setUp() throws Exception {
mTestLooper = new TestLooper();
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
+ InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
when(mContextSpy.getSystemService(eq(Context.VIBRATOR_SERVICE))).thenReturn(mVibratorMock);
+ when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
when(mContextSpy.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManagerMock);
when(mVibratorMock.getDefaultHapticFeedbackIntensity())
.thenReturn(Vibrator.VIBRATION_INTENSITY_MEDIUM);
@@ -145,6 +152,7 @@ public class VibratorServiceTest {
.thenReturn(new ComponentName("", ""));
when(mPowerManagerInternalMock.getLowPowerState(PowerManager.ServiceType.VIBRATION))
.thenReturn(mPowerSaveStateMock);
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
@@ -168,8 +176,9 @@ public class VibratorServiceTest {
VibratorService service = new VibratorService(mContextSpy,
new VibratorService.Injector() {
@Override
- VibratorService.NativeWrapper getNativeWrapper() {
- return mNativeWrapperMock;
+ VibratorController createVibratorController(
+ VibratorController.OnVibrationCompleteListener listener) {
+ return new VibratorController(0, listener, mNativeWrapperMock);
}
@Override
@@ -189,19 +198,19 @@ public class VibratorServiceTest {
@Test
public void createService_initializesNativeService() {
createService();
- verify(mNativeWrapperMock).vibratorInit(notNull());
- verify(mNativeWrapperMock).vibratorOff();
+ verify(mNativeWrapperMock).init(eq(0), notNull());
+ verify(mNativeWrapperMock).off();
}
@Test
public void hasVibrator_withVibratorHalPresent_returnsTrue() {
- when(mNativeWrapperMock.vibratorExists()).thenReturn(true);
+ when(mNativeWrapperMock.isAvailable()).thenReturn(true);
assertTrue(createService().hasVibrator());
}
@Test
public void hasVibrator_withNoVibratorHalPresent_returnsFalse() {
- when(mNativeWrapperMock.vibratorExists()).thenReturn(false);
+ when(mNativeWrapperMock.isAvailable()).thenReturn(false);
assertFalse(createService().hasVibrator());
}
@@ -217,8 +226,17 @@ public class VibratorServiceTest {
}
@Test
+ public void hasAmplitudeControl_withInputDevices_returnsTrue() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
+ mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
+ assertTrue(createService().hasAmplitudeControl());
+ }
+
+ @Test
public void areEffectsSupported_withNullResultFromNative_returnsSupportUnknown() {
- when(mNativeWrapperMock.vibratorGetSupportedEffects()).thenReturn(null);
+ when(mNativeWrapperMock.getSupportedEffects()).thenReturn(null);
assertArrayEquals(new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN},
createService().areEffectsSupported(new int[]{VibrationEffect.EFFECT_CLICK}));
}
@@ -227,7 +245,7 @@ public class VibratorServiceTest {
public void areEffectsSupported_withSomeEffectsSupported_returnsSupportYesAndNoForEffects() {
int[] effects = new int[]{VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK};
- when(mNativeWrapperMock.vibratorGetSupportedEffects())
+ when(mNativeWrapperMock.getSupportedEffects())
.thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
assertArrayEquals(
new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_YES,
@@ -247,7 +265,7 @@ public class VibratorServiceTest {
@Test
public void arePrimitivesSupported_withNullResultFromNative_returnsAlwaysFalse() {
mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
- when(mNativeWrapperMock.vibratorGetSupportedPrimitives()).thenReturn(null);
+ when(mNativeWrapperMock.getSupportedPrimitives()).thenReturn(null);
assertArrayEquals(new boolean[]{false, false},
createService().arePrimitivesSupported(new int[]{
@@ -259,7 +277,7 @@ public class VibratorServiceTest {
@Test
public void arePrimitivesSupported_withSomeSupportedPrimitives_returnsBasedOnNativeResult() {
mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
- when(mNativeWrapperMock.vibratorGetSupportedPrimitives())
+ when(mNativeWrapperMock.getSupportedPrimitives())
.thenReturn(new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK});
assertArrayEquals(new boolean[]{true, false},
@@ -275,7 +293,7 @@ public class VibratorServiceTest {
assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1,
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS));
- verify(mNativeWrapperMock).vibratorAlwaysOnEnable(
+ verify(mNativeWrapperMock).alwaysOnEnable(
eq(1L), eq((long) VibrationEffect.EFFECT_CLICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG));
}
@@ -286,8 +304,8 @@ public class VibratorServiceTest {
assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1,
VibrationEffect.createOneShot(100, 255), ALARM_ATTRS));
- verify(mNativeWrapperMock, never()).vibratorAlwaysOnDisable(anyLong());
- verify(mNativeWrapperMock, never()).vibratorAlwaysOnEnable(anyLong(), anyLong(), anyLong());
+ verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong());
+ verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
}
@Test
@@ -295,15 +313,15 @@ public class VibratorServiceTest {
mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, null, ALARM_ATTRS));
- verify(mNativeWrapperMock).vibratorAlwaysOnDisable(eq(1L));
+ verify(mNativeWrapperMock).alwaysOnDisable(eq(1L));
}
@Test
public void setAlwaysOnEffect_withoutCapability_ignoresEffect() {
assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1,
VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS));
- verify(mNativeWrapperMock, never()).vibratorAlwaysOnDisable(anyLong());
- verify(mNativeWrapperMock, never()).vibratorAlwaysOnEnable(anyLong(), anyLong(), anyLong());
+ verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong());
+ verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
}
@Test
@@ -322,9 +340,9 @@ public class VibratorServiceTest {
vibrate(createService(), VibrationEffect.createOneShot(100, 100), RINGTONE_ATTRS);
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock, never()).vibratorOn(eq(1L), anyLong());
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(10L), anyLong());
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(100L), anyLong());
+ inOrderVerifier.verify(mNativeWrapperMock, never()).on(eq(1L), anyLong());
+ inOrderVerifier.verify(mNativeWrapperMock).on(eq(10L), anyLong());
+ inOrderVerifier.verify(mNativeWrapperMock).on(eq(100L), anyLong());
}
@Test
@@ -375,6 +393,22 @@ public class VibratorServiceTest {
}
@Test
+ public void vibrate_withOneShotAndInputDevices_vibratesInputDevices() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
+ setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
+ VibratorService service = createService();
+ Mockito.clearInvocations(mNativeWrapperMock);
+
+ VibrationEffect effect = VibrationEffect.createOneShot(100, 128);
+ vibrate(service, effect);
+ assertFalse(service.isVibrating());
+
+ verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
+ verify(mNativeWrapperMock, never()).on(anyLong(), anyLong());
+ }
+
+ @Test
public void vibrate_withOneShotAndAmplitudeControl_turnsVibratorOnAndSetsAmplitude() {
mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibratorService service = createService();
@@ -383,9 +417,9 @@ public class VibratorServiceTest {
vibrate(service, VibrationEffect.createOneShot(100, 128));
assertTrue(service.isVibrating());
- verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
- verify(mNativeWrapperMock).vibratorSetAmplitude(eq(128));
+ verify(mNativeWrapperMock).off();
+ verify(mNativeWrapperMock).on(eq(100L), gt(0L));
+ verify(mNativeWrapperMock).setAmplitude(eq(128));
}
@Test
@@ -396,26 +430,45 @@ public class VibratorServiceTest {
vibrate(service, VibrationEffect.createOneShot(100, 128));
assertTrue(service.isVibrating());
- verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
- verify(mNativeWrapperMock, never()).vibratorSetAmplitude(anyInt());
+ verify(mNativeWrapperMock).off();
+ verify(mNativeWrapperMock).on(eq(100L), gt(0L));
+ verify(mNativeWrapperMock, never()).setAmplitude(anyInt());
}
@Test
public void vibrate_withPrebaked_performsEffect() {
- when(mNativeWrapperMock.vibratorGetSupportedEffects())
+ when(mNativeWrapperMock.getSupportedEffects())
.thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
VibratorService service = createService();
Mockito.clearInvocations(mNativeWrapperMock);
vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
- verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorPerformEffect(eq((long) VibrationEffect.EFFECT_CLICK),
+ verify(mNativeWrapperMock).off();
+ verify(mNativeWrapperMock).perform(eq((long) VibrationEffect.EFFECT_CLICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), gt(0L));
}
@Test
+ public void vibrate_withPrebakedAndInputDevices_vibratesFallbackWaveformOnInputDevices()
+ throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
+ setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
+ VibratorService service = createService();
+ Mockito.clearInvocations(mNativeWrapperMock);
+
+ vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+ assertFalse(service.isVibrating());
+
+ // Wait for VibrateThread to turn input device vibrator ON.
+ Thread.sleep(5);
+ verify(mIInputManagerMock).vibrate(eq(1), any(), any());
+ verify(mNativeWrapperMock, never()).on(anyLong(), anyLong());
+ verify(mNativeWrapperMock, never()).perform(anyLong(), anyLong(), anyLong());
+ }
+
+ @Test
public void vibrate_withComposed_performsEffect() {
mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
VibratorService service = createService();
@@ -429,9 +482,8 @@ public class VibratorServiceTest {
ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor =
ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class);
- verify(mNativeWrapperMock).vibratorOff();
- verify(mNativeWrapperMock).vibratorPerformComposedEffect(
- primitivesCaptor.capture(), gt(0L));
+ verify(mNativeWrapperMock).off();
+ verify(mNativeWrapperMock).compose(primitivesCaptor.capture(), gt(0L));
// Check all primitive effect fields are passed down to the HAL.
assertEquals(1, primitivesCaptor.getValue().length);
@@ -442,6 +494,27 @@ public class VibratorServiceTest {
}
@Test
+ public void vibrate_withComposedAndInputDevices_vibratesInputDevices()
+ throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
+ when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
+ when(mIInputManagerMock.getInputDevice(2)).thenReturn(createInputDeviceWithVibrator(2));
+ setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
+ VibratorService service = createService();
+ Mockito.clearInvocations(mNativeWrapperMock);
+
+ VibrationEffect effect = VibrationEffect.startComposition()
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
+ .compose();
+ vibrate(service, effect);
+ assertFalse(service.isVibrating());
+
+ verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
+ verify(mIInputManagerMock).vibrate(eq(2), eq(effect), any());
+ verify(mNativeWrapperMock, never()).compose(any(), anyLong());
+ }
+
+ @Test
public void vibrate_withWaveform_controlsVibratorAmplitudeDuringTotalVibrationTime()
throws Exception {
mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
@@ -455,12 +528,12 @@ public class VibratorServiceTest {
// Wait for VibrateThread to finish: 10ms 100, 10ms 200, 10ms 50.
Thread.sleep(40);
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(30L), anyLong());
- inOrderVerifier.verify(mNativeWrapperMock).vibratorSetAmplitude(eq(100));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorSetAmplitude(eq(200));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorSetAmplitude(eq(50));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
+ inOrderVerifier.verify(mNativeWrapperMock).off();
+ inOrderVerifier.verify(mNativeWrapperMock).on(eq(30L), anyLong());
+ inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(100));
+ inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(200));
+ inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(50));
+ inOrderVerifier.verify(mNativeWrapperMock).off();
}
@Test
@@ -473,12 +546,12 @@ public class VibratorServiceTest {
doAnswer(invocation -> {
Thread.currentThread().sleep(stepDuration / 4);
return null;
- }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
+ }).when(mNativeWrapperMock).on(anyLong(), anyLong());
// 25% of each waveform step will be spent on the native setAmplitude() call..
doAnswer(invocation -> {
Thread.currentThread().sleep(stepDuration / 4);
return null;
- }).when(mNativeWrapperMock).vibratorSetAmplitude(anyInt());
+ }).when(mNativeWrapperMock).setAmplitude(anyInt());
VibratorService service = createService();
@@ -500,42 +573,61 @@ public class VibratorServiceTest {
}
@Test
+ public void vibrate_withWaveformAndInputDevices_vibratesInputDevices() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
+ setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
+ VibratorService service = createService();
+ Mockito.clearInvocations(mNativeWrapperMock);
+
+ VibrationEffect effect = VibrationEffect.createWaveform(
+ new long[]{10, 10, 10}, new int[]{100, 200, 50}, -1);
+ vibrate(service, effect);
+ assertFalse(service.isVibrating());
+
+ // Wait for VibrateThread to turn input device vibrator ON.
+ Thread.sleep(5);
+ verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
+ verify(mNativeWrapperMock, never()).on(anyLong(), anyLong());
+ }
+
+ @Test
public void vibrate_withOneShotAndNativeCallbackTriggered_finishesVibration() {
VibratorService service = createService();
doAnswer(invocation -> {
service.onVibrationComplete(invocation.getArgument(1));
return null;
- }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
+ }).when(mNativeWrapperMock).on(anyLong(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
+ inOrderVerifier.verify(mNativeWrapperMock).off();
+ inOrderVerifier.verify(mNativeWrapperMock).on(eq(100L), gt(0L));
+ inOrderVerifier.verify(mNativeWrapperMock).off();
}
@Test
public void vibrate_withPrebakedAndNativeCallbackTriggered_finishesVibration() {
- when(mNativeWrapperMock.vibratorGetSupportedEffects())
+ when(mNativeWrapperMock.getSupportedEffects())
.thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
VibratorService service = createService();
doAnswer(invocation -> {
service.onVibrationComplete(invocation.getArgument(2));
return 10_000L; // 10s
- }).when(mNativeWrapperMock).vibratorPerformEffect(anyLong(), anyLong(), anyLong());
+ }).when(mNativeWrapperMock).perform(anyLong(), anyLong(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformEffect(
+ inOrderVerifier.verify(mNativeWrapperMock).off();
+ inOrderVerifier.verify(mNativeWrapperMock).perform(
eq((long) VibrationEffect.EFFECT_CLICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG),
gt(0L));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
+ inOrderVerifier.verify(mNativeWrapperMock).off();
}
@Test
@@ -545,7 +637,7 @@ public class VibratorServiceTest {
doAnswer(invocation -> {
service.onVibrationComplete(invocation.getArgument(1));
return null;
- }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
+ }).when(mNativeWrapperMock).on(anyLong(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{1, 3, 1, 2}, -1);
@@ -554,11 +646,11 @@ public class VibratorServiceTest {
// Wait for VibrateThread to finish: 1ms OFF, 3ms ON, 1ms OFF, 2ms ON.
Thread.sleep(15);
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock, times(2)).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(3L), anyLong());
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(2L), anyLong());
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
+ inOrderVerifier.verify(mNativeWrapperMock, times(2)).off();
+ inOrderVerifier.verify(mNativeWrapperMock).on(eq(3L), anyLong());
+ inOrderVerifier.verify(mNativeWrapperMock).off();
+ inOrderVerifier.verify(mNativeWrapperMock).on(eq(2L), anyLong());
+ inOrderVerifier.verify(mNativeWrapperMock).off();
}
@Test
@@ -568,7 +660,7 @@ public class VibratorServiceTest {
doAnswer(invocation -> {
service.onVibrationComplete(invocation.getArgument(1));
return null;
- }).when(mNativeWrapperMock).vibratorPerformComposedEffect(any(), anyLong());
+ }).when(mNativeWrapperMock).compose(any(), anyLong());
Mockito.clearInvocations(mNativeWrapperMock);
VibrationEffect effect = VibrationEffect.startComposition()
@@ -577,14 +669,14 @@ public class VibratorServiceTest {
vibrate(service, effect);
InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
- inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformComposedEffect(
+ inOrderVerifier.verify(mNativeWrapperMock).off();
+ inOrderVerifier.verify(mNativeWrapperMock).compose(
any(VibrationEffect.Composition.PrimitiveEffect[].class), gt(0L));
- inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
+ inOrderVerifier.verify(mNativeWrapperMock).off();
}
@Test
- public void cancelVibrate_withDeviceVibrating_callsVibratorOff() {
+ public void cancelVibrate_withDeviceVibrating_callsoff() {
VibratorService service = createService();
vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
assertTrue(service.isVibrating());
@@ -592,7 +684,7 @@ public class VibratorServiceTest {
service.cancelVibrate(service);
assertFalse(service.isVibrating());
- verify(mNativeWrapperMock).vibratorOff();
+ verify(mNativeWrapperMock).off();
}
@Test
@@ -602,24 +694,23 @@ public class VibratorServiceTest {
service.cancelVibrate(service);
assertFalse(service.isVibrating());
- verify(mNativeWrapperMock, never()).vibratorOff();
+ verify(mNativeWrapperMock, never()).off();
}
@Test
public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
VibratorService service = createService();
- doAnswer(invocation -> {
- service.onVibrationComplete(invocation.getArgument(1));
- return null;
- }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
service.registerVibratorStateListener(mVibratorStateListenerMock);
- verify(mVibratorStateListenerMock).onVibrating(false);
- Mockito.clearInvocations(mVibratorStateListenerMock);
vibrate(service, VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE));
+ service.cancelVibrate(service);
+
InOrder inOrderVerifier = inOrder(mVibratorStateListenerMock);
+ // First notification done when listener is registered.
+ inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(false);
inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(true));
inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false));
+ inOrderVerifier.verifyNoMoreInteractions();
}
@Test
@@ -659,16 +750,16 @@ public class VibratorServiceTest {
vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK),
RINGTONE_ATTRS);
- verify(mNativeWrapperMock).vibratorPerformEffect(
+ verify(mNativeWrapperMock).perform(
eq((long) VibrationEffect.EFFECT_CLICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), anyLong());
- verify(mNativeWrapperMock).vibratorPerformEffect(
+ verify(mNativeWrapperMock).perform(
eq((long) VibrationEffect.EFFECT_TICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), anyLong());
- verify(mNativeWrapperMock).vibratorPerformEffect(
+ verify(mNativeWrapperMock).perform(
eq((long) VibrationEffect.EFFECT_DOUBLE_CLICK),
eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), anyLong());
- verify(mNativeWrapperMock, never()).vibratorPerformEffect(
+ verify(mNativeWrapperMock, never()).perform(
eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), anyLong());
}
@@ -696,14 +787,14 @@ public class VibratorServiceTest {
Thread.sleep(15);
// Alarm vibration is never scaled.
- verify(mNativeWrapperMock).vibratorSetAmplitude(eq(100));
+ verify(mNativeWrapperMock).setAmplitude(eq(100));
// Notification vibrations will be scaled with SCALE_VERY_HIGH.
- verify(mNativeWrapperMock).vibratorSetAmplitude(intThat(amplitude -> amplitude > 150));
+ verify(mNativeWrapperMock).setAmplitude(intThat(amplitude -> amplitude > 150));
// Haptic feedback vibrations will be scaled with SCALE_LOW.
- verify(mNativeWrapperMock).vibratorSetAmplitude(
+ verify(mNativeWrapperMock).setAmplitude(
intThat(amplitude -> amplitude < 100 && amplitude > 50));
// Ringtone vibration is off.
- verify(mNativeWrapperMock, never()).vibratorSetAmplitude(eq(255));
+ verify(mNativeWrapperMock, never()).setAmplitude(eq(255));
}
@Test
@@ -733,7 +824,7 @@ public class VibratorServiceTest {
vibrate(service, effect, RINGTONE_ATTRS);
// Ringtone vibration is off, so only the other 3 are propagated to native.
- verify(mNativeWrapperMock, times(3)).vibratorPerformComposedEffect(
+ verify(mNativeWrapperMock, times(3)).compose(
primitivesCaptor.capture(), anyLong());
List<VibrationEffect.Composition.PrimitiveEffect[]> values =
@@ -792,7 +883,12 @@ public class VibratorServiceTest {
}
private void mockVibratorCapabilities(int capabilities) {
- when(mNativeWrapperMock.vibratorGetCapabilities()).thenReturn((long) capabilities);
+ when(mNativeWrapperMock.getCapabilities()).thenReturn((long) capabilities);
+ }
+
+ private InputDevice createInputDeviceWithVibrator(int id) {
+ return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0,
+ null, /* hasVibrator= */ true, false, false);
}
private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index d10e075c5136..de9a5e4f0fe7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -18,13 +18,17 @@ package com.android.server.hdmi;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
+import android.annotation.NonNull;
import android.content.Context;
import android.hardware.hdmi.HdmiControlManager;
+import android.os.Looper;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings.Global;
@@ -38,15 +42,21 @@ import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
@SmallTest
@Presubmit
@RunWith(JUnit4.class)
public final class HdmiCecConfigTest {
private static final String TAG = "HdmiCecConfigTest";
+ private static final int TIMEOUT_CONTENT_CHANGE_SEC = 4;
+
private Context mContext;
@Mock private HdmiCecConfig.StorageAdapter mStorageAdapter;
+ @Mock private HdmiCecConfig.SettingChangeListener mSettingChangeListener;
@Before
public void setUp() throws Exception {
@@ -1019,4 +1029,105 @@ public final class HdmiCecConfigTest {
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED));
}
+
+ @Test
+ public void registerChangeListener_SharedPref_BasicSanity() {
+ HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+ mContext, mStorageAdapter,
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+ + "<cec-settings>"
+ + " <setting name=\"system_audio_mode_muting\""
+ + " value-type=\"int\""
+ + " user-configurable=\"true\">"
+ + " <allowed-values>"
+ + " <value int-value=\"0\" />"
+ + " <value int-value=\"1\" />"
+ + " </allowed-values>"
+ + " <default-value int-value=\"1\" />"
+ + " </setting>"
+ + "</cec-settings>", null);
+ hdmiCecConfig.registerChangeListener(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+ mSettingChangeListener);
+ hdmiCecConfig.setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+ HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
+ verify(mSettingChangeListener).onChange(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
+ }
+
+ @Test
+ public void removeChangeListener_SharedPref_BasicSanity() {
+ HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+ mContext, mStorageAdapter,
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+ + "<cec-settings>"
+ + " <setting name=\"system_audio_mode_muting\""
+ + " value-type=\"int\""
+ + " user-configurable=\"true\">"
+ + " <allowed-values>"
+ + " <value int-value=\"0\" />"
+ + " <value int-value=\"1\" />"
+ + " </allowed-values>"
+ + " <default-value int-value=\"1\" />"
+ + " </setting>"
+ + "</cec-settings>", null);
+ hdmiCecConfig.registerChangeListener(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+ mSettingChangeListener);
+ hdmiCecConfig.removeChangeListener(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+ mSettingChangeListener);
+ hdmiCecConfig.setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+ HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
+ verify(mSettingChangeListener, never()).onChange(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
+ }
+
+ /**
+ * Externally modified Global Settings still need to be supported. This test verifies that
+ * setting change notification is being forwarded to listeners registered via HdmiCecConfig.
+ */
+ @Test
+ public void globalSettingObserver_BasicSanity() throws Exception {
+ CountDownLatch notifyLatch = new CountDownLatch(1);
+ // Get current value of the setting in the system.
+ String val = Global.getString(mContext.getContentResolver(), Global.HDMI_CONTROL_ENABLED);
+ HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+ mContext, mStorageAdapter,
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+ + "<cec-settings>"
+ + " <setting name=\"hdmi_cec_enabled\""
+ + " value-type=\"int\""
+ + " user-configurable=\"true\">"
+ + " <allowed-values>"
+ + " <value int-value=\"0\" />"
+ + " <value int-value=\"1\" />"
+ + " </allowed-values>"
+ + " <default-value int-value=\"1\" />"
+ + " </setting>"
+ + "</cec-settings>", null);
+ hdmiCecConfig.registerGlobalSettingsObserver(Looper.getMainLooper());
+ HdmiCecConfig.SettingChangeListener latchUpdateListener =
+ new HdmiCecConfig.SettingChangeListener() {
+ @Override
+ public void onChange(@NonNull @HdmiControlManager.CecSettingName String setting) {
+ notifyLatch.countDown();
+ assertThat(setting).isEqualTo(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED);
+ }
+ };
+ hdmiCecConfig.registerChangeListener(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+ latchUpdateListener);
+ // Flip the value of the setting.
+ Global.putString(mContext.getContentResolver(), Global.HDMI_CONTROL_ENABLED,
+ ((val == null || val.equals("1")) ? "0" : "1"));
+ if (!notifyLatch.await(TIMEOUT_CONTENT_CHANGE_SEC, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for the notify callback");
+ }
+ hdmiCecConfig.unregisterGlobalSettingsObserver();
+ // Restore the previous value of the setting in the system.
+ Global.putString(mContext.getContentResolver(), Global.HDMI_CONTROL_ENABLED, val);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 9d767cd94853..819bd01992cb 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -521,6 +521,41 @@ public class HdmiControlServiceTest {
assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures);
}
+ @Test
+ public void initializeCec_14_doesNotBroadcastReportFeatures() {
+ mNativeWrapper.clearResultMessages();
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
+ mHdmiControlService.setControlEnabled(true);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
+ Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
+ Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
+ mMyPlaybackDevice.getRcProfile(), mMyPlaybackDevice.getRcFeatures(),
+ mMyPlaybackDevice.getDeviceFeatures());
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportFeatures);
+ }
+
+ @Test
+ public void initializeCec_20_reportsFeaturesBroadcast() {
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ mHdmiControlService.setControlEnabled(true);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
+ Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
+ Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
+ mMyPlaybackDevice.getRcProfile(), mMyPlaybackDevice.getRcFeatures(),
+ mMyPlaybackDevice.getDeviceFeatures());
+ assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures);
+ }
+
private static class VolumeControlFeatureCallback extends
IHdmiCecVolumeControlFeatureListener.Stub {
boolean mCallbackReceived = false;
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
index 8afc3d30efa3..1db5544871bf 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
@@ -18,6 +18,8 @@ package com.android.server.inputmethod;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -38,9 +40,9 @@ public class InputMethodManagerServiceTests {
(displayId) -> {
switch (displayId) {
case SYSTEM_DECORATION_SUPPORT_DISPLAY_ID:
- return true;
+ return DISPLAY_IME_POLICY_LOCAL;
case NO_SYSTEM_DECORATION_SUPPORT_DISPLAY_ID:
- return false;
+ return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
default:
throw new IllegalArgumentException("Unknown displayId=" + displayId);
}
@@ -49,7 +51,7 @@ public class InputMethodManagerServiceTests {
static InputMethodManagerService.ImeDisplayValidator sMustNotBeCalledChecker =
(displayId) -> {
fail("Should not pass to display config check for this test case.");
- return false;
+ return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
};
@Test
diff --git a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
index 3f1653718fe7..00cef8fb8481 100644
--- a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
@@ -59,7 +59,7 @@ import java.util.Objects;
@Presubmit
public class ControllerImplTest {
- private static final long ARBITRARY_TIME = 12345L;
+ private static final long ARBITRARY_TIME_MILLIS = 12345L;
private static final LocationTimeZoneEvent USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1 =
createLocationTimeZoneEvent(EVENT_TYPE_SUCCESS, asList("Europe/London"));
@@ -935,7 +935,7 @@ public class ControllerImplTest {
private static LocationTimeZoneEvent createLocationTimeZoneEvent(
int eventType, @Nullable List<String> timeZoneIds) {
LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder()
- .setElapsedRealtimeNanos(ARBITRARY_TIME)
+ .setElapsedRealtimeMillis(ARBITRARY_TIME_MILLIS)
.setEventType(eventType);
if (timeZoneIds != null) {
builder.setTimeZoneIds(timeZoneIds);
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
index 3846be09a6c1..34cefec4655b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -134,7 +134,7 @@ public class DexoptUtilsTest {
private List<SharedLibraryInfo> createMockSharedLibrary(String [] sharedLibrary) {
SharedLibraryInfo info = new SharedLibraryInfo(null, null, Arrays.asList(sharedLibrary),
- null, 0L, SharedLibraryInfo.TYPE_STATIC, null, null, null);
+ null, 0L, SharedLibraryInfo.TYPE_STATIC, null, null, null, false /* isNative */);
ArrayList<SharedLibraryInfo> libraries = new ArrayList<>();
libraries.add(info);
return libraries;
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
index eedc9781aa40..c42f936d3ab4 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
@@ -110,6 +110,8 @@ public class RollbackStoreTest {
@Rule
public TemporaryFolder mFolder = new TemporaryFolder();
+ @Rule
+ public TemporaryFolder mHistoryDir = new TemporaryFolder();
private File mRollbackDir;
@@ -117,7 +119,7 @@ public class RollbackStoreTest {
@Before
public void setUp() throws Exception {
- mRollbackStore = new RollbackStore(mFolder.getRoot());
+ mRollbackStore = new RollbackStore(mFolder.getRoot(), mHistoryDir.getRoot());
mRollbackDir = mFolder.newFolder(ID + "");
mFolder.newFile("rollback.json");
}
@@ -202,6 +204,8 @@ public class RollbackStoreTest {
origRb.info.getPackages().add(pkgInfo1);
origRb.info.getPackages().add(pkgInfo2);
+ origRb.setState(Rollback.ROLLBACK_STATE_AVAILABLE, "hello world");
+
RollbackStore.saveRollback(origRb);
List<Rollback> loadedRollbacks = mRollbackStore.loadRollbacks();
@@ -324,10 +328,26 @@ public class RollbackStoreTest {
assertThat(expectedFile.exists()).isFalse();
}
- private void assertRollbacksAreEquivalent(Rollback b, Rollback a) {
- assertThat(b.info.getRollbackId()).isEqualTo(ID);
+ @Test
+ public void saveToHistoryAndLoad() {
+ Rollback origRb = mRollbackStore.createNonStagedRollback(
+ ID, USER, INSTALLER, null, new SparseIntArray(0));
+ mRollbackStore.saveRollbackToHistory(origRb);
+
+ List<Rollback> loadedRollbacks = mRollbackStore.loadHistorialRollbacks();
+ assertThat(loadedRollbacks).hasSize(1);
+ Rollback loadedRb = loadedRollbacks.get(0);
+
+ assertRollbacksAreEquivalentExcludingBackupDir(loadedRb, origRb);
+ }
+ private void assertRollbacksAreEquivalent(Rollback b, Rollback a) {
assertThat(b.getBackupDir()).isEqualTo(a.getBackupDir());
+ assertRollbacksAreEquivalentExcludingBackupDir(b, a);
+ }
+
+ private void assertRollbacksAreEquivalentExcludingBackupDir(Rollback b, Rollback a) {
+ assertThat(b.info.getRollbackId()).isEqualTo(ID);
assertThat(b.isRestoreUserDataInProgress())
.isEqualTo(a.isRestoreUserDataInProgress());
@@ -337,6 +357,7 @@ public class RollbackStoreTest {
assertThat(b.isEnabling()).isEqualTo(a.isEnabling());
assertThat(b.isAvailable()).isEqualTo(a.isAvailable());
assertThat(b.isCommitted()).isEqualTo(a.isCommitted());
+ assertThat(b.getStateDescription()).isEqualTo(a.getStateDescription());
assertThat(b.isStaged()).isEqualTo(a.isStaged());
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
index cd2c9230221c..cf1ed4815a74 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
@@ -123,7 +123,7 @@ public class RollbackUnitTest {
public void deletedRollbackCannotBeMadeAvailable() {
Rollback rollback = new Rollback(123, new File("/test/testing"), -1, USER, INSTALLER);
- rollback.delete(mMockDataHelper);
+ rollback.delete(mMockDataHelper, "test");
assertThat(rollback.isDeleted()).isTrue();
@@ -221,7 +221,7 @@ public class RollbackUnitTest {
PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true);
rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2));
- rollback.delete(mMockDataHelper);
+ rollback.delete(mMockDataHelper, "test");
assertThat(rollback.isDeleted()).isTrue();
@@ -247,7 +247,7 @@ public class RollbackUnitTest {
verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds));
- rollback.delete(mMockDataHelper);
+ rollback.delete(mMockDataHelper, "test");
verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(111));
verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(222));
@@ -269,7 +269,7 @@ public class RollbackUnitTest {
verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds));
- rollback.delete(mMockDataHelper);
+ rollback.delete(mMockDataHelper, "test");
verify(mMockDataHelper, never())
.destroyAppDataSnapshot(anyInt(), pkgRollbackInfoFor(PKG_2), anyInt());
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index e101a06feb4e..4a44005e9602 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -245,7 +245,7 @@ public class TimeDetectorServiceTest {
}
@Override
- public void handleAutoTimeDetectionChanged() {
+ public void handleAutoTimeConfigChanged() {
mHandleAutoTimeDetectionChangedCalled = true;
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index 1be074dfa5a3..c23fb8028224 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -16,6 +16,9 @@
package com.android.server.timedetector;
+import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
+import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -25,32 +28,39 @@ import static org.junit.Assert.fail;
import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
-import android.icu.util.Calendar;
-import android.icu.util.GregorianCalendar;
-import android.icu.util.TimeZone;
import android.os.TimestampedValue;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.timedetector.TimeDetectorStrategy.Origin;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
@RunWith(AndroidJUnit4.class)
public class TimeDetectorStrategyImplTest {
- private static final TimestampedValue<Long> ARBITRARY_CLOCK_INITIALIZATION_INFO =
+ private static final Instant TIME_LOWER_BOUND = createUtcTime(2009, 1, 1, 12, 0, 0);
+
+ private static final TimestampedValue<Instant> ARBITRARY_CLOCK_INITIALIZATION_INFO =
new TimestampedValue<>(
123456789L /* realtimeClockMillis */,
- createUtcTime(2008, 5, 23, 12, 0, 0));
+ createUtcTime(2010, 5, 23, 12, 0, 0));
+
+ // This is the traditional ordering for time detection on Android.
+ private static final @Origin int [] PROVIDERS_PRIORITY = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
/**
* An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO}
* time. Can be used as the basis for time suggestions.
*/
- private static final long ARBITRARY_TEST_TIME_MILLIS = createUtcTime(2018, 1, 1, 12, 0, 0);
+ private static final Instant ARBITRARY_TEST_TIME = createUtcTime(2018, 1, 1, 12, 0, 0);
private static final int ARBITRARY_SLOT_INDEX = 123456;
@@ -67,10 +77,10 @@ public class TimeDetectorStrategyImplTest {
.pokeAutoTimeDetectionEnabled(true);
int slotIndex = ARBITRARY_SLOT_INDEX;
- long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
+ Instant testTime = ARBITRARY_TEST_TIME;
TelephonyTimeSuggestion timeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
mScript.simulateTimePassing()
.simulateTelephonyTimeSuggestion(timeSuggestion);
@@ -106,9 +116,9 @@ public class TimeDetectorStrategyImplTest {
// Send the first time signal. It should be used.
{
TelephonyTimeSuggestion timeSuggestion1 =
- mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME_MILLIS);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME);
- // Increment the the device clocks to simulate the passage of time.
+ // Increment the device clocks to simulate the passage of time.
mScript.simulateTimePassing(clockIncrementMillis);
long expectedSystemClockMillis1 =
@@ -157,13 +167,13 @@ public class TimeDetectorStrategyImplTest {
// uses the lowest slotIndex when multiple telephony suggestions are available.
int slotIndex1 = ARBITRARY_SLOT_INDEX;
int slotIndex2 = ARBITRARY_SLOT_INDEX + 1;
- long slotIndex1TimeMillis = ARBITRARY_TEST_TIME_MILLIS;
- long slotIndex2TimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(1).toMillis();
+ Instant slotIndex1Time = ARBITRARY_TEST_TIME;
+ Instant slotIndex2Time = ARBITRARY_TEST_TIME.plus(Duration.ofDays(1));
// Make a suggestion with slotIndex2.
{
TelephonyTimeSuggestion slotIndex2TimeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time);
mScript.simulateTimePassing();
long expectedSystemClockMillis =
@@ -180,7 +190,7 @@ public class TimeDetectorStrategyImplTest {
// Now make a different suggestion with slotIndex1.
{
TelephonyTimeSuggestion slotIndex1TimeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1TimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1Time);
mScript.simulateTimePassing();
long expectedSystemClockMillis =
@@ -198,7 +208,7 @@ public class TimeDetectorStrategyImplTest {
// slotIndex1 suggestion will still "win".
{
TelephonyTimeSuggestion slotIndex2TimeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time);
mScript.simulateTimePassing();
mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion)
@@ -213,7 +223,7 @@ public class TimeDetectorStrategyImplTest {
// is in an older "bucket".
{
TelephonyTimeSuggestion slotIndex2TimeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time);
mScript.simulateTimePassing();
long expectedSystemClockMillis =
@@ -232,7 +242,7 @@ public class TimeDetectorStrategyImplTest {
int slotIndex = ARBITRARY_SLOT_INDEX;
TelephonyTimeSuggestion timeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME_MILLIS);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME);
mScript.simulateTimePassing()
.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking()
@@ -246,11 +256,11 @@ public class TimeDetectorStrategyImplTest {
.pokeThresholds(systemClockUpdateThreshold)
.pokeAutoTimeDetectionEnabled(true);
- long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
+ Instant testTime = ARBITRARY_TEST_TIME;
int slotIndex = ARBITRARY_SLOT_INDEX;
TelephonyTimeSuggestion timeSuggestion1 =
- mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
// Initialize the strategy / device with a time set from a telephony suggestion.
@@ -300,6 +310,23 @@ public class TimeDetectorStrategyImplTest {
}
@Test
+ public void telephonyTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(true);
+
+ int slotIndex = ARBITRARY_SLOT_INDEX;
+ Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
+
+ TelephonyTimeSuggestion timeSuggestion =
+ mScript.generateTelephonyTimeSuggestion(
+ slotIndex, suggestedTime);
+
+ mScript.simulateTelephonyTimeSuggestion(timeSuggestion)
+ .verifySystemClockWasNotSetAndResetCallTracking()
+ .assertLatestTelephonySuggestion(slotIndex, null);
+ }
+
+ @Test
public void testSuggestTelephonyTime_timeDetectionToggled() {
final int clockIncrementMillis = 100;
final int systemClockUpdateThreshold = 2000;
@@ -308,9 +335,9 @@ public class TimeDetectorStrategyImplTest {
.pokeAutoTimeDetectionEnabled(false);
int slotIndex = ARBITRARY_SLOT_INDEX;
- long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
+ Instant testTime = ARBITRARY_TEST_TIME;
TelephonyTimeSuggestion timeSuggestion1 =
- mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
// Simulate time passing.
@@ -366,9 +393,9 @@ public class TimeDetectorStrategyImplTest {
.pokeAutoTimeDetectionEnabled(true);
int slotIndex = ARBITRARY_SLOT_INDEX;
- long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
+ Instant testTime = ARBITRARY_TEST_TIME;
TelephonyTimeSuggestion telephonySuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
mScript.simulateTimePassing();
@@ -397,7 +424,7 @@ public class TimeDetectorStrategyImplTest {
.pokeAutoTimeDetectionEnabled(false);
ManualTimeSuggestion timeSuggestion =
- mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS);
+ mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME);
mScript.simulateTimePassing();
@@ -416,9 +443,9 @@ public class TimeDetectorStrategyImplTest {
int slotIndex = ARBITRARY_SLOT_INDEX;
// Simulate a telephony suggestion.
- long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
+ Instant testTime = ARBITRARY_TEST_TIME;
TelephonyTimeSuggestion telephonyTimeSuggestion =
- mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
+ mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
// Simulate the passage of time.
mScript.simulateTimePassing();
@@ -441,9 +468,9 @@ public class TimeDetectorStrategyImplTest {
mScript.simulateTimePassing();
// Simulate a manual suggestion 1 day different from the auto suggestion.
- long manualTimeMillis = testTimeMillis + Duration.ofDays(1).toMillis();
+ Instant manualTime = testTime.plus(Duration.ofDays(1));
ManualTimeSuggestion manualTimeSuggestion =
- mScript.generateManualTimeSuggestion(manualTimeMillis);
+ mScript.generateManualTimeSuggestion(manualTime);
mScript.simulateTimePassing();
long expectedManualClockMillis =
@@ -469,16 +496,13 @@ public class TimeDetectorStrategyImplTest {
.assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
}
- /**
- * Manual suggestions should be ignored if auto time is enabled.
- */
@Test
- public void testSuggestManualTime_autoTimeEnabled() {
+ public void manualTimeSuggestion_isIgnored_whenAutoTimeEnabled() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true);
ManualTimeSuggestion timeSuggestion =
- mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS);
+ mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME);
mScript.simulateTimePassing()
.simulateManualTimeSuggestion(timeSuggestion, false /* expectedResult */)
@@ -486,12 +510,25 @@ public class TimeDetectorStrategyImplTest {
}
@Test
+ public void manualTimeSuggestion_ignoresTimeLowerBound() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(false);
+ Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
+
+ ManualTimeSuggestion timeSuggestion =
+ mScript.generateManualTimeSuggestion(suggestedTime);
+
+ mScript.simulateManualTimeSuggestion(timeSuggestion, true /* expectedResult */)
+ .verifySystemClockWasSetAndResetCallTracking(suggestedTime.toEpochMilli());
+ }
+
+ @Test
public void testSuggestNetworkTime_autoTimeEnabled() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true);
NetworkTimeSuggestion timeSuggestion =
- mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS);
+ mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME);
mScript.simulateTimePassing();
@@ -507,7 +544,7 @@ public class TimeDetectorStrategyImplTest {
.pokeAutoTimeDetectionEnabled(false);
NetworkTimeSuggestion timeSuggestion =
- mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS);
+ mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME);
mScript.simulateTimePassing()
.simulateNetworkTimeSuggestion(timeSuggestion)
@@ -520,16 +557,16 @@ public class TimeDetectorStrategyImplTest {
.pokeAutoTimeDetectionEnabled(true);
// Three obviously different times that could not be mistaken for each other.
- long networkTimeMillis1 = ARBITRARY_TEST_TIME_MILLIS;
- long networkTimeMillis2 = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(30).toMillis();
- long telephonyTimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(60).toMillis();
+ Instant networkTime1 = ARBITRARY_TEST_TIME;
+ Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
+ Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(60));
// A small increment used to simulate the passage of time, but not enough to interfere with
// macro-level time changes associated with suggestion age.
final long smallTimeIncrementMillis = 101;
// A network suggestion is made. It should be used because there is no telephony suggestion.
NetworkTimeSuggestion networkTimeSuggestion1 =
- mScript.generateNetworkTimeSuggestion(networkTimeMillis1);
+ mScript.generateNetworkTimeSuggestion(networkTime1);
mScript.simulateTimePassing(smallTimeIncrementMillis)
.simulateNetworkTimeSuggestion(networkTimeSuggestion1)
.verifySystemClockWasSetAndResetCallTracking(
@@ -548,7 +585,7 @@ public class TimeDetectorStrategyImplTest {
// Now a telephony suggestion is made. Telephony suggestions are prioritized over network
// suggestions so it should "win".
TelephonyTimeSuggestion telephonyTimeSuggestion =
- mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeMillis);
+ mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
mScript.simulateTimePassing(smallTimeIncrementMillis)
.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(
@@ -568,7 +605,7 @@ public class TimeDetectorStrategyImplTest {
// Now another network suggestion is made. Telephony suggestions are prioritized over
// network suggestions so the latest telephony suggestion should still "win".
NetworkTimeSuggestion networkTimeSuggestion2 =
- mScript.generateNetworkTimeSuggestion(networkTimeMillis2);
+ mScript.generateNetworkTimeSuggestion(networkTime2);
mScript.simulateTimePassing(smallTimeIncrementMillis)
.simulateNetworkTimeSuggestion(networkTimeSuggestion2)
.verifySystemClockWasNotSetAndResetCallTracking();
@@ -612,6 +649,87 @@ public class TimeDetectorStrategyImplTest {
assertNull(mScript.peekBestTelephonySuggestion());
}
+ @Test
+ public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(true);
+
+ Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
+ NetworkTimeSuggestion timeSuggestion = mScript
+ .generateNetworkTimeSuggestion(suggestedTime);
+
+ mScript.simulateNetworkTimeSuggestion(timeSuggestion)
+ .verifySystemClockWasNotSetAndResetCallTracking()
+ .assertLatestNetworkSuggestion(null);
+ }
+
+ @Test
+ public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(true);
+
+ Instant networkTime = ARBITRARY_TEST_TIME;
+ Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
+
+ NetworkTimeSuggestion networkTimeSuggestion =
+ mScript.generateNetworkTimeSuggestion(networkTime);
+ TelephonyTimeSuggestion telephonyTimeSuggestion =
+ mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
+
+ mScript.simulateNetworkTimeSuggestion(networkTimeSuggestion)
+ .simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
+ .assertLatestNetworkSuggestion(networkTimeSuggestion)
+ .assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
+ .verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli());
+ }
+
+ @Test
+ public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(true);
+
+ Instant networkTime = ARBITRARY_TEST_TIME;
+ Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
+
+ NetworkTimeSuggestion networkTimeSuggestion =
+ mScript.generateNetworkTimeSuggestion(networkTime);
+ TelephonyTimeSuggestion telephonyTimeSuggestion =
+ mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
+
+ mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
+ .simulateNetworkTimeSuggestion(networkTimeSuggestion)
+ .assertLatestNetworkSuggestion(networkTimeSuggestion)
+ .assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
+ .verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli());
+ }
+
+ @Test
+ public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(true);
+
+ NetworkTimeSuggestion timeSuggestion =
+ mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME);
+
+ mScript.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
+ .verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
+ }
+
+ @Test
+ public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() {
+ mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+ .pokeAutoTimeDetectionEnabled(true)
+ .pokeAutoOriginPriorities(new int[]{ORIGIN_TELEPHONY});
+
+ NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion(
+ ARBITRARY_TEST_TIME);
+
+ mScript.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
+ .verifySystemClockWasNotSetAndResetCallTracking();
+ }
+
/**
* A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving
* like the real thing should, it also asserts preconditions.
@@ -622,6 +740,7 @@ public class TimeDetectorStrategyImplTest {
private long mElapsedRealtimeMillis;
private long mSystemClockMillis;
private int mSystemClockUpdateThresholdMillis = 2000;
+ private int[] mAutoOriginPriorities = PROVIDERS_PRIORITY;
// Tracking operations.
private boolean mSystemClockWasSet;
@@ -637,6 +756,16 @@ public class TimeDetectorStrategyImplTest {
}
@Override
+ public Instant autoTimeLowerBound() {
+ return TIME_LOWER_BOUND;
+ }
+
+ @Override
+ public int[] getAutoOriginPriorities() {
+ return mAutoOriginPriorities;
+ }
+
+ @Override
public void acquireWakeLock() {
if (mWakeLockAcquired) {
fail("Wake lock already acquired");
@@ -685,6 +814,10 @@ public class TimeDetectorStrategyImplTest {
mAutoTimeDetectionEnabled = enabled;
}
+ void pokeAutoOriginPriorities(@Origin int[] autoOriginPriorities) {
+ mAutoOriginPriorities = autoOriginPriorities;
+ }
+
long peekElapsedRealtimeMillis() {
return mElapsedRealtimeMillis;
}
@@ -703,7 +836,10 @@ public class TimeDetectorStrategyImplTest {
}
void verifySystemClockNotSet() {
- assertFalse(mSystemClockWasSet);
+ assertFalse(
+ String.format("System clock was manipulated and set to %s(=%s)",
+ Instant.ofEpochMilli(mSystemClockMillis), mSystemClockMillis),
+ mSystemClockWasSet);
}
void verifySystemClockWasSet(long expectedSystemClockMillis) {
@@ -739,9 +875,9 @@ public class TimeDetectorStrategyImplTest {
return this;
}
- Script pokeFakeClocks(TimestampedValue<Long> timeInfo) {
+ Script pokeFakeClocks(TimestampedValue<Instant> timeInfo) {
mFakeCallback.pokeElapsedRealtimeMillis(timeInfo.getReferenceTimeMillis());
- mFakeCallback.pokeSystemClockMillis(timeInfo.getValue());
+ mFakeCallback.pokeSystemClockMillis(timeInfo.getValue().toEpochMilli());
return this;
}
@@ -750,6 +886,11 @@ public class TimeDetectorStrategyImplTest {
return this;
}
+ Script pokeAutoOriginPriorities(@Origin int[] autoOriginPriorites) {
+ mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorites);
+ return this;
+ }
+
long peekElapsedRealtimeMillis() {
return mFakeCallback.peekElapsedRealtimeMillis();
}
@@ -765,7 +906,13 @@ public class TimeDetectorStrategyImplTest {
Script simulateManualTimeSuggestion(
ManualTimeSuggestion timeSuggestion, boolean expectedResult) {
- assertEquals(expectedResult, mTimeDetectorStrategy.suggestManualTime(timeSuggestion));
+ String errorMessage = expectedResult
+ ? "Manual time suggestion was ignored, but expected to be accepted."
+ : "Manual time suggestion was accepted, but expected to be ignored.";
+ assertEquals(
+ errorMessage,
+ expectedResult,
+ mTimeDetectorStrategy.suggestManualTime(timeSuggestion));
return this;
}
@@ -776,7 +923,7 @@ public class TimeDetectorStrategyImplTest {
Script simulateAutoTimeDetectionToggle() {
mFakeCallback.simulateAutoTimeZoneDetectionToggle();
- mTimeDetectorStrategy.handleAutoTimeDetectionChanged();
+ mTimeDetectorStrategy.handleAutoTimeConfigChanged();
return this;
}
@@ -808,7 +955,10 @@ public class TimeDetectorStrategyImplTest {
* White box test info: Asserts the latest suggestion for the slotIndex is as expected.
*/
Script assertLatestTelephonySuggestion(int slotIndex, TelephonyTimeSuggestion expected) {
- assertEquals(expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex));
+ assertEquals(
+ "Expected to see " + expected + " at slotIndex=" + slotIndex + ", but got "
+ + mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex),
+ expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex));
return this;
}
@@ -840,9 +990,11 @@ public class TimeDetectorStrategyImplTest {
* Generates a ManualTimeSuggestion using the current elapsed realtime clock for the
* reference time.
*/
- ManualTimeSuggestion generateManualTimeSuggestion(long timeMillis) {
+ ManualTimeSuggestion generateManualTimeSuggestion(Instant suggestedTime) {
TimestampedValue<Long> utcTime =
- new TimestampedValue<>(mFakeCallback.peekElapsedRealtimeMillis(), timeMillis);
+ new TimestampedValue<>(
+ mFakeCallback.peekElapsedRealtimeMillis(),
+ suggestedTime.toEpochMilli());
return new ManualTimeSuggestion(utcTime);
}
@@ -850,21 +1002,33 @@ public class TimeDetectorStrategyImplTest {
* Generates a {@link TelephonyTimeSuggestion} using the current elapsed realtime clock for
* the reference time.
*/
- TelephonyTimeSuggestion generateTelephonyTimeSuggestion(int slotIndex, Long timeMillis) {
- TimestampedValue<Long> time = null;
- if (timeMillis != null) {
- time = new TimestampedValue<>(peekElapsedRealtimeMillis(), timeMillis);
- }
+ TelephonyTimeSuggestion generateTelephonyTimeSuggestion(int slotIndex, long timeMillis) {
+ TimestampedValue<Long> time =
+ new TimestampedValue<>(peekElapsedRealtimeMillis(), timeMillis);
return createTelephonyTimeSuggestion(slotIndex, time);
}
/**
+ * Generates a {@link TelephonyTimeSuggestion} using the current elapsed realtime clock for
+ * the reference time.
+ */
+ TelephonyTimeSuggestion generateTelephonyTimeSuggestion(
+ int slotIndex, Instant suggestedTime) {
+ if (suggestedTime == null) {
+ return createTelephonyTimeSuggestion(slotIndex, null);
+ }
+ return generateTelephonyTimeSuggestion(slotIndex, suggestedTime.toEpochMilli());
+ }
+
+ /**
* Generates a NetworkTimeSuggestion using the current elapsed realtime clock for the
* reference time.
*/
- NetworkTimeSuggestion generateNetworkTimeSuggestion(long timeMillis) {
+ NetworkTimeSuggestion generateNetworkTimeSuggestion(Instant suggestedTime) {
TimestampedValue<Long> utcTime =
- new TimestampedValue<>(mFakeCallback.peekElapsedRealtimeMillis(), timeMillis);
+ new TimestampedValue<>(
+ mFakeCallback.peekElapsedRealtimeMillis(),
+ suggestedTime.toEpochMilli());
return new NetworkTimeSuggestion(utcTime);
}
@@ -884,11 +1048,9 @@ public class TimeDetectorStrategyImplTest {
.build();
}
- private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute,
- int second) {
- Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC"));
- cal.clear();
- cal.set(year, monthInYear - 1, day, hourOfDay, minute, second);
- return cal.getTimeInMillis();
+ private static Instant createUtcTime(int year, int monthInYear, int day, int hourOfDay,
+ int minute, int second) {
+ return LocalDateTime.of(year, monthInYear, day, hourOfDay, minute, second)
+ .toInstant(ZoneOffset.UTC);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
new file mode 100644
index 000000000000..fa8e36741bcc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.input.IInputDevicesChangedListener;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.Process;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
+import android.view.InputDevice;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/**
+ * Tests for {@link InputDeviceDelegate}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:InputDeviceDelegateTest
+ */
+@Presubmit
+public class InputDeviceDelegateTest {
+
+ private static final int UID = Process.ROOT_UID;
+ private static final String PACKAGE_NAME = "package";
+ private static final String REASON = "some reason";
+ private static final VibrationAttributes VIBRATION_ATTRIBUTES =
+ new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_ALARM).build();
+
+ @Rule public MockitoRule rule = MockitoJUnit.rule();
+
+ @Mock private IInputManager mIInputManagerMock;
+
+ private TestLooper mTestLooper;
+ private ContextWrapper mContextSpy;
+ private InputDeviceDelegate mInputDeviceDelegate;
+ private IInputDevicesChangedListener mIInputDevicesChangedListener;
+
+ @Before
+ public void setUp() throws Exception {
+ mTestLooper = new TestLooper();
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
+ InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
+
+ when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
+ doAnswer(invocation -> mIInputDevicesChangedListener = invocation.getArgument(0))
+ .when(mIInputManagerMock).registerInputDevicesChangedListener(any());
+
+ mInputDeviceDelegate = new InputDeviceDelegate(
+ mContextSpy, new Handler(mTestLooper.getLooper()));
+ }
+
+ @Test
+ public void onInputDeviceAdded_withSettingsDisabled_ignoresNewDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
+ mInputDeviceDelegate.onInputDeviceAdded(1);
+
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock, never()).getInputDevice(anyInt());
+ }
+
+ @Test
+ public void onInputDeviceAdded_withDeviceWithoutVibrator_ignoresNewDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+
+ when(mIInputManagerMock.getInputDevice(eq(1)))
+ .thenReturn(createInputDeviceWithoutVibrator(1));
+ updateInputDevices(new int[]{1});
+
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock).getInputDevice(eq(1));
+ }
+
+ @Test
+ public void onInputDeviceAdded_withDeviceWithVibrator_addsNewDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
+ updateInputDevices(new int[]{1});
+
+ assertTrue(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock).getInputDevice(eq(1));
+ }
+
+ @Test
+ public void onInputDeviceChanged_withSettingsDisabled_ignoresDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false);
+
+ updateInputDevices(new int[]{1});
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock, never()).getInputDevice(anyInt());
+ }
+
+ @Test
+ public void onInputDeviceChanged_deviceLosesVibrator_removesDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(eq(1)))
+ .thenReturn(createInputDeviceWithVibrator(1), createInputDeviceWithoutVibrator(1));
+
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertTrue(mInputDeviceDelegate.isAvailable());
+
+ updateInputDevices(new int[]{1});
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock, times(2)).getInputDevice(eq(1));
+ }
+
+ @Test
+ public void onInputDeviceChanged_deviceLost_removesDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(eq(1)))
+ .thenReturn(createInputDeviceWithVibrator(1), (InputDevice) null);
+
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertTrue(mInputDeviceDelegate.isAvailable());
+
+ updateInputDevices(new int[]{1});
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock, times(2)).getInputDevice(eq(1));
+ }
+
+ @Test
+ public void onInputDeviceChanged_deviceAddsVibrator_addsDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(eq(1)))
+ .thenReturn(createInputDeviceWithoutVibrator(1), createInputDeviceWithVibrator(1));
+
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+
+ updateInputDevices(new int[]{1});
+ assertTrue(mInputDeviceDelegate.isAvailable());
+ verify(mIInputManagerMock, times(2)).getInputDevice(eq(1));
+ }
+
+ @Test
+ public void onInputDeviceRemoved_removesDevice() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(
+ createInputDeviceWithoutVibrator(1));
+ when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
+
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertTrue(mInputDeviceDelegate.isAvailable());
+
+ updateInputDevices(new int[]{1});
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ }
+
+ @Test
+ public void updateInputDeviceVibrators_usesFlagToLoadDeviceList() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
+ when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
+
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertTrue(mInputDeviceDelegate.isAvailable());
+
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ }
+
+ @Test
+ public void updateInputDeviceVibrators_withDeviceWithoutVibrator_deviceIsIgnored()
+ throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mIInputManagerMock.getInputDevice(eq(1)))
+ .thenReturn(createInputDeviceWithoutVibrator(1));
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ }
+
+ @Test
+ public void vibrateIfAvailable_withNoInputDevice_returnsFalse() {
+ VibrationEffect effect = VibrationEffect.createOneShot(100, 255);
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ assertFalse(mInputDeviceDelegate.vibrateIfAvailable(
+ UID, PACKAGE_NAME, effect, REASON, VIBRATION_ATTRIBUTES));
+ }
+
+ @Test
+ public void vibrateIfAvailable_withInputDevices_returnsTrueAndVibratesAllDevices()
+ throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
+ when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+
+ VibrationEffect effect = VibrationEffect.createOneShot(100, 255);
+ assertTrue(mInputDeviceDelegate.vibrateIfAvailable(
+ UID, PACKAGE_NAME, effect, REASON, VIBRATION_ATTRIBUTES));
+ verify(mIInputManagerMock).vibrate(eq(1), same(effect), any());
+ verify(mIInputManagerMock).vibrate(eq(2), same(effect), any());
+ }
+
+ @Test
+ public void cancelVibrateIfAvailable_withNoInputDevice_returnsFalse() throws Exception {
+ assertFalse(mInputDeviceDelegate.isAvailable());
+ assertFalse(mInputDeviceDelegate.cancelVibrateIfAvailable());
+ verify(mIInputManagerMock, never()).cancelVibrate(anyInt(), any());
+ }
+
+ @Test
+ public void cancelVibrateIfAvailable_withInputDevices_returnsTrueAndStopsAllDevices()
+ throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
+ when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
+ when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
+ mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+
+ assertTrue(mInputDeviceDelegate.isAvailable());
+ assertTrue(mInputDeviceDelegate.cancelVibrateIfAvailable());
+ verify(mIInputManagerMock).cancelVibrate(eq(1), any());
+ verify(mIInputManagerMock).cancelVibrate(eq(2), any());
+ }
+
+ private void updateInputDevices(int[] deviceIds) throws Exception {
+ int[] deviceIdsAndGenerations = new int[deviceIds.length * 2];
+ for (int i = 0; i < deviceIdsAndGenerations.length; i += 2) {
+ deviceIdsAndGenerations[i] = deviceIds[i / 2];
+ deviceIdsAndGenerations[i + 1] = 2; // update by increasing it's generation to 2.
+ }
+ // Force initialization of mIInputDevicesChangedListener, if it still haven't
+ InputManager.getInstance().getInputDeviceIds();
+ mIInputDevicesChangedListener.onInputDevicesChanged(deviceIdsAndGenerations);
+ // Makes sure all callbacks from InputDeviceDelegate are executed.
+ mTestLooper.dispatchAll();
+ }
+
+ private InputDevice createInputDeviceWithVibrator(int id) {
+ return createInputDevice(id, /* hasVibrator= */ true);
+ }
+
+ private InputDevice createInputDeviceWithoutVibrator(int id) {
+ return createInputDevice(id, /* hasVibrator= */ false);
+ }
+
+ private InputDevice createInputDevice(int id, boolean hasVibrator) {
+ return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0,
+ null, hasVibrator, false, false);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 2cc999283184..04c2cb3b1148 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -18,6 +18,7 @@ package com.android.server.vibrator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
@@ -33,6 +34,7 @@ import android.media.AudioManager;
import android.os.Handler;
import android.os.UserHandle;
import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
@@ -271,6 +273,15 @@ public class VibrationSettingsTest {
mVibrationSettings.getCurrentIntensity(VibrationAttributes.USAGE_RINGTONE));
}
+ @Test
+ public void getFallbackEffect_returnsEffectsFromSettings() {
+ assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_TICK));
+ assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_TEXTURE_TICK));
+ assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_CLICK));
+ assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_HEAVY_CLICK));
+ assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_DOUBLE_CLICK));
+ }
+
private void setUserSetting(String settingName, int value) {
Settings.System.putIntForUser(
mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
new file mode 100644
index 000000000000..1f163bd3282b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.ContextWrapper;
+import android.hardware.vibrator.IVibrator;
+import android.os.IBinder;
+import android.os.IVibratorStateListener;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProviderRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/**
+ * Tests for {@link VibratorController}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:VibratorControllerTest
+ */
+@Presubmit
+public class VibratorControllerTest {
+
+ @Rule public MockitoRule rule = MockitoJUnit.rule();
+ @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+
+ @Mock private VibratorController.OnVibrationCompleteListener mOnCompleteListenerMock;
+ @Mock private VibratorController.NativeWrapper mNativeWrapperMock;
+ @Mock private IVibratorStateListener mVibratorStateListenerMock;
+ @Mock private IBinder mVibratorStateListenerBinderMock;
+
+ private TestLooper mTestLooper;
+ private ContextWrapper mContextSpy;
+
+ @Before
+ public void setUp() throws Exception {
+ mTestLooper = new TestLooper();
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
+
+ ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
+ when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
+ when(mVibratorStateListenerMock.asBinder()).thenReturn(mVibratorStateListenerBinderMock);
+ }
+
+ private VibratorController createController() {
+ return new VibratorController(/* vibratorId= */ 0, mOnCompleteListenerMock,
+ mNativeWrapperMock);
+ }
+
+ private VibratorController createController(int vibratorId) {
+ return new VibratorController(vibratorId, mOnCompleteListenerMock, mNativeWrapperMock);
+ }
+
+ @Test
+ public void createController_initializesNativeWrapper() {
+ int vibratorId = 13;
+ VibratorController controller = createController(vibratorId);
+ assertEquals(vibratorId, controller.getVibratorId());
+ verify(mNativeWrapperMock).init(eq(vibratorId), notNull());
+ }
+
+ @Test
+ public void isAvailable_withVibratorHalPresent_returnsTrue() {
+ when(mNativeWrapperMock.isAvailable()).thenReturn(true);
+ assertTrue(createController().isAvailable());
+ }
+
+ @Test
+ public void isAvailable_withNoVibratorHalPresent_returnsFalse() {
+ when(mNativeWrapperMock.isAvailable()).thenReturn(false);
+ assertFalse(createController().isAvailable());
+ }
+
+ @Test
+ public void hasCapability_withSupport_returnsTrue() {
+ mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ assertTrue(createController().hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL));
+ }
+
+ @Test
+ public void hasCapability_withNoSupport_returnsFalse() {
+ assertFalse(createController().hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL));
+ assertFalse(createController().hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL));
+ assertFalse(createController().hasCapability(IVibrator.CAP_COMPOSE_EFFECTS));
+ assertFalse(createController().hasCapability(IVibrator.CAP_EXTERNAL_CONTROL));
+ assertFalse(createController().hasCapability(IVibrator.CAP_ON_CALLBACK));
+ }
+
+ @Test
+ public void areEffectsSupported_withNullResultFromNative_returnsSupportUnknown() {
+ when(mNativeWrapperMock.getSupportedEffects()).thenReturn(null);
+ assertArrayEquals(new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN},
+ createController().areEffectsSupported(new int[]{VibrationEffect.EFFECT_CLICK}));
+ }
+
+ @Test
+ public void areEffectsSupported_withSomeEffectsSupported_returnsSupportYesAndNoForEffects() {
+ int[] effects = new int[]{VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK};
+
+ when(mNativeWrapperMock.getSupportedEffects())
+ .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
+ assertArrayEquals(
+ new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_YES,
+ Vibrator.VIBRATION_EFFECT_SUPPORT_NO},
+ createController().areEffectsSupported(effects));
+ }
+
+ @Test
+ public void arePrimitivesSupported_withoutComposeCapability_returnsAlwaysFalse() {
+ assertArrayEquals(new boolean[]{false, false},
+ createController().arePrimitivesSupported(new int[]{
+ VibrationEffect.Composition.PRIMITIVE_CLICK,
+ VibrationEffect.Composition.PRIMITIVE_TICK
+ }));
+ }
+
+ @Test
+ public void arePrimitivesSupported_withNullResultFromNative_returnsAlwaysFalse() {
+ mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+ when(mNativeWrapperMock.getSupportedPrimitives()).thenReturn(null);
+
+ assertArrayEquals(new boolean[]{false, false},
+ createController().arePrimitivesSupported(new int[]{
+ VibrationEffect.Composition.PRIMITIVE_CLICK,
+ VibrationEffect.Composition.PRIMITIVE_QUICK_RISE
+ }));
+ }
+
+ @Test
+ public void arePrimitivesSupported_withSomeSupportedPrimitives_returnsBasedOnNativeResult() {
+ mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+ when(mNativeWrapperMock.getSupportedPrimitives())
+ .thenReturn(new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK});
+
+ assertArrayEquals(new boolean[]{true, false},
+ createController().arePrimitivesSupported(new int[]{
+ VibrationEffect.Composition.PRIMITIVE_CLICK,
+ VibrationEffect.Composition.PRIMITIVE_QUICK_RISE
+ }));
+ }
+
+ @Test
+ public void setExternalControl_withCapability_enablesExternalControl() {
+ mockVibratorCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
+ VibratorController controller = createController();
+ assertFalse(controller.isUnderExternalControl());
+
+ controller.setExternalControl(true);
+ assertTrue(controller.isUnderExternalControl());
+
+ controller.setExternalControl(false);
+ assertFalse(controller.isUnderExternalControl());
+
+ InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
+ inOrderVerifier.verify(mNativeWrapperMock).setExternalControl(eq(true));
+ inOrderVerifier.verify(mNativeWrapperMock).setExternalControl(eq(false));
+ }
+
+ @Test
+ public void setExternalControl_withNoCapability_ignoresExternalControl() {
+ VibratorController controller = createController();
+ assertFalse(controller.isUnderExternalControl());
+
+ controller.setExternalControl(true);
+ assertFalse(controller.isUnderExternalControl());
+
+ verify(mNativeWrapperMock, never()).setExternalControl(anyBoolean());
+ }
+
+ @Test
+ public void updateAlwaysOn_withCapability_enablesAlwaysOnEffect() {
+ mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+ VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
+ createController().updateAlwaysOn(1, effect);
+
+ verify(mNativeWrapperMock).alwaysOnEnable(
+ eq(1L), eq((long) VibrationEffect.EFFECT_CLICK),
+ eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM));
+ }
+
+ @Test
+ public void updateAlwaysOn_withNullEffect_disablesAlwaysOnEffect() {
+ mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+ createController().updateAlwaysOn(1, null);
+ verify(mNativeWrapperMock).alwaysOnDisable(eq(1L));
+ }
+
+ @Test
+ public void updateAlwaysOn_withoutCapability_ignoresEffect() {
+ VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
+ createController().updateAlwaysOn(1, effect);
+
+ verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong());
+ verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
+ }
+
+ @Test
+ public void on_withDuration_turnsVibratorOn() {
+ VibratorController controller = createController();
+ controller.on(100, 10);
+
+ assertTrue(controller.isVibrating());
+ verify(mNativeWrapperMock).on(eq(100L), eq(10L));
+ }
+
+ @Test
+ public void on_withPrebaked_performsEffect() {
+ when(mNativeWrapperMock.perform(anyLong(), anyLong(), anyLong())).thenReturn(10L);
+ VibratorController controller = createController();
+
+ VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
+ controller.on(effect, 11);
+
+ assertTrue(controller.isVibrating());
+ verify(mNativeWrapperMock).perform(eq((long) VibrationEffect.EFFECT_CLICK),
+ eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), eq(11L));
+ }
+
+ @Test
+ public void on_withComposed_performsEffect() {
+ mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+ VibratorController controller = createController();
+
+ VibrationEffect.Composed effect = (VibrationEffect.Composed)
+ VibrationEffect.startComposition()
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
+ .compose();
+ controller.on(effect, 12);
+
+ ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor =
+ ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class);
+
+ assertTrue(controller.isVibrating());
+ verify(mNativeWrapperMock).compose(primitivesCaptor.capture(), eq(12L));
+
+ // Check all primitive effect fields are passed down to the HAL.
+ assertEquals(1, primitivesCaptor.getValue().length);
+ VibrationEffect.Composition.PrimitiveEffect primitive = primitivesCaptor.getValue()[0];
+ assertEquals(VibrationEffect.Composition.PRIMITIVE_CLICK, primitive.id);
+ assertEquals(0.5f, primitive.scale, /* delta= */ 1e-2);
+ assertEquals(10, primitive.delay);
+ }
+
+ @Test
+ public void off_turnsOffVibrator() {
+ VibratorController controller = createController();
+ controller.on(100, 1);
+ assertTrue(controller.isVibrating());
+
+ controller.off();
+ controller.off();
+ assertFalse(controller.isVibrating());
+ verify(mNativeWrapperMock, times(2)).off();
+ }
+
+ @Test
+ public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
+ VibratorController controller = createController();
+
+ controller.registerVibratorStateListener(mVibratorStateListenerMock);
+ controller.on(10, 1);
+ controller.on(100, 2);
+ controller.off();
+ controller.off();
+
+ InOrder inOrderVerifier = inOrder(mVibratorStateListenerMock);
+ // First notification done when listener is registered.
+ inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(false);
+ inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(true));
+ inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false));
+ inOrderVerifier.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void unregisterVibratorStateListener_callbackNotTriggeredAfter() throws Exception {
+ VibratorController controller = createController();
+
+ controller.registerVibratorStateListener(mVibratorStateListenerMock);
+ verify(mVibratorStateListenerMock).onVibrating(false);
+
+ controller.on(10, 1);
+ verify(mVibratorStateListenerMock).onVibrating(true);
+
+ controller.unregisterVibratorStateListener(mVibratorStateListenerMock);
+ Mockito.clearInvocations(mVibratorStateListenerMock);
+
+ controller.on(10, 1);
+ verifyNoMoreInteractions(mVibratorStateListenerMock);
+ }
+
+ private void mockVibratorCapabilities(int capabilities) {
+ when(mNativeWrapperMock.getCapabilities()).thenReturn((long) capabilities);
+ }
+}
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 7f4f3dd58812..0ed037c7e70a 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -65,8 +65,6 @@
android:turnScreenOn="true" />
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ResumeWhilePausingActivity"
android:resumeWhilePausing="true"/>
- <activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity"
- android:showWhenLocked="true" android:allowEmbedded="true"/>
<activity android:name="com.android.server.wm.ActivityLeakTests$DetectLeakActivity" />
</application>
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index bded3f9de9ba..565bf8b615c7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -422,7 +422,7 @@ public class ActivityStarterTests extends WindowTestsBase {
// verify that values are passed to the modifier. Values are passed thrice -- two for
// setting initial state, another when task is created.
verify(modifier, times(3)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options),
- anyInt(), any(), any());
+ anyInt(), any(), any(), any());
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 017ed883e2bd..475e462bdd3d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -34,6 +34,7 @@ import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.timeout;
import android.app.WaitResult;
import android.content.pm.ActivityInfo;
@@ -45,6 +46,8 @@ import androidx.test.filters.MediumTest;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.TimeUnit;
+
/**
* Tests for the {@link ActivityTaskSupervisor} class.
*
@@ -190,4 +193,16 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase {
assertThat(allowedOnUntrusted).isFalse();
}
+
+ /**
+ * We need to launch home again after user unlocked for those displays that do not have
+ * encryption aware home app.
+ */
+ @Test
+ public void testStartHomeAfterUserUnlocked() {
+ mSupervisor.onUserUnlocked(0);
+ waitHandlerIdle(mAtm.mH);
+ verify(mRootWindowContainer, timeout(TimeUnit.SECONDS.toMillis(10)))
+ .startHomeOnEmptyDisplays("userUnlocked");
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 21bdc9e7785e..79b2da187680 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -236,8 +236,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
final WindowState activity = createBaseApplicationWindow();
activity.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
- policy.adjustWindowParamsLw(activity, activity.mAttrs, 0 /* callingPid */,
- 0 /* callingUid */);
+ policy.adjustWindowParamsLw(activity, activity.mAttrs);
}
private WindowState createApplicationWindow() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index 94ffcdab4fa7..20775e84fd8f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -107,11 +107,9 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
}
void addWindow(WindowState win) {
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
- mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, callingPid, callingUid);
- assertEquals(WindowManagerGlobal.ADD_OKAY,
- mDisplayPolicy.validateAddingWindowLw(win.mAttrs, callingPid, callingUid));
+ mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs);
+ assertEquals(WindowManagerGlobal.ADD_OKAY, mDisplayPolicy.validateAddingWindowLw(
+ win.mAttrs, Binder.getCallingPid(), Binder.getCallingUid()));
mDisplayPolicy.addWindowLw(win, win.mAttrs);
win.mHasSurface = true;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index b346bb810b2e..eaedd58001c1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -167,7 +168,7 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
mBaseSettingsStorage, mOverrideSettingsStorage);
SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
overrideSettings.mShouldShowSystemDecors = true;
- overrideSettings.mShouldShowIme = true;
+ overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
@@ -176,8 +177,8 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
getStoredDisplayAttributeValue(mOverrideSettingsStorage, "name"));
assertEquals("Attribute value must be stored", "true",
getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors"));
- assertEquals("Attribute value must be stored", "true",
- getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowIme"));
+ assertEquals("Attribute value must be stored", "0",
+ getStoredDisplayAttributeValue(mOverrideSettingsStorage, "imePolicy"));
}
@Test
@@ -195,7 +196,7 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
mBaseSettingsStorage, mOverrideSettingsStorage);
SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
overrideSettings.mShouldShowSystemDecors = true;
- overrideSettings.mShouldShowIme = true;
+ overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
@@ -204,8 +205,8 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
getStoredDisplayAttributeValue(mOverrideSettingsStorage, "name"));
assertEquals("Attribute value must be stored", "true",
getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors"));
- assertEquals("Attribute value must be stored", "true",
- getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowIme"));
+ assertEquals("Attribute value must be stored", "0",
+ getStoredDisplayAttributeValue(mOverrideSettingsStorage, "imePolicy"));
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 2ca5583c48c3..9e4cd161c478 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -22,6 +22,8 @@ import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED;
import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -49,7 +51,6 @@ import androidx.test.filters.SmallTest;
import com.android.server.LocalServices;
import com.android.server.policy.WindowManagerPolicy;
-import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
import org.junit.Before;
import org.junit.Test;
@@ -319,17 +320,21 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
}
@Test
- public void testPrimaryDisplayShouldShowIme() {
- assertTrue(mDisplayWindowSettings.shouldShowImeLocked(mPrimaryDisplay));
+ public void testPrimaryDisplayImePolicy() {
+ assertEquals(DISPLAY_IME_POLICY_LOCAL,
+ mDisplayWindowSettings.getImePolicyLocked(mPrimaryDisplay));
- mDisplayWindowSettings.setShouldShowImeLocked(mPrimaryDisplay, false);
+ mDisplayWindowSettings.setDisplayImePolicy(mPrimaryDisplay,
+ DISPLAY_IME_POLICY_FALLBACK_DISPLAY);
- assertTrue(mDisplayWindowSettings.shouldShowImeLocked(mPrimaryDisplay));
+ assertEquals(DISPLAY_IME_POLICY_LOCAL,
+ mDisplayWindowSettings.getImePolicyLocked(mPrimaryDisplay));
}
@Test
- public void testSecondaryDisplayDefaultToNotShowIme() {
- assertFalse(mDisplayWindowSettings.shouldShowImeLocked(mSecondaryDisplay));
+ public void testSecondaryDisplayDefaultToShowImeOnFallbackDisplay() {
+ assertEquals(DISPLAY_IME_POLICY_FALLBACK_DISPLAY,
+ mDisplayWindowSettings.getImePolicyLocked(mSecondaryDisplay));
}
@Test
@@ -400,17 +405,18 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
}
@Test
- public void testShouldShowImeWithinForceDesktopMode() {
+ public void testShouldShowImeOnDisplayWithinForceDesktopMode() {
try {
// Presume display enabled force desktop mode from developer options.
final DisplayContent dc = createMockSimulatedDisplay();
mWm.setForceDesktopModeOnExternalDisplays(true);
final WindowManagerInternal wmInternal = LocalServices.getService(
WindowManagerInternal.class);
- // Make sure WindowManagerInter#shouldShowIme as true is due to
- // mForceDesktopModeOnExternalDisplays as true.
- assertFalse(mWm.mDisplayWindowSettings.shouldShowImeLocked(dc));
- assertTrue(wmInternal.shouldShowIme(dc.getDisplayId()));
+ // Make sure WindowManagerInter#getDisplayImePolicy is SHOW_IME_ON_DISPLAY is due to
+ // mForceDesktopModeOnExternalDisplays being SHOW_IME_ON_DISPLAY.
+ assertEquals(DISPLAY_IME_POLICY_FALLBACK_DISPLAY,
+ mWm.mDisplayWindowSettings.getImePolicyLocked(dc));
+ assertEquals(DISPLAY_IME_POLICY_LOCAL, wmInternal.getDisplayImePolicy(dc.getDisplayId()));
} finally {
mWm.setForceDesktopModeOnExternalDisplays(false);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java
index a9f6b50d4be5..f75c98f39323 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java
@@ -18,14 +18,28 @@ package com.android.server.wm;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+import android.view.IWindowManager;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import com.android.server.inputmethod.InputMethodManagerService;
import com.android.server.inputmethod.InputMethodMenuController;
@@ -45,10 +59,34 @@ import org.junit.runner.RunWith;
public class InputMethodMenuControllerTest extends WindowTestsBase {
private InputMethodMenuController mController;
+ private TestDisplayContent mSecondaryDisplay;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
mController = new InputMethodMenuController(mock(InputMethodManagerService.class));
+
+ // Mock addWindowTokenWithOptions to create a test window token.
+ IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
+ spyOn(wms);
+ doAnswer(invocation -> {
+ Object[] args = invocation.getArguments();
+ final IBinder token = (IBinder) args[0];
+ final int windowType = (int) args[1];
+ new WindowToken(mWm, token, windowType, true /* persistOnEmpty */,
+ mDefaultDisplay, true /* ownerCanManageAppTokens */, 1000 /* ownerUid */,
+ false /* roundedCornerOverlay */, true /* fromClientToken */);
+ return WindowManagerGlobal.ADD_OKAY;
+ }).when(wms).addWindowTokenWithOptions(any(), anyInt(), anyInt(), any(), anyString());
+
+ mSecondaryDisplay = new TestDisplayContent.Builder(mAtm, 1000, 1000).build();
+
+ // Mock DisplayManagerGlobal to return test display when obtaining Display instance.
+ final int displayId = mSecondaryDisplay.getDisplayId();
+ final Display display = mSecondaryDisplay.getDisplay();
+ DisplayManagerGlobal displayManagerGlobal = DisplayManagerGlobal.getInstance();
+ spyOn(displayManagerGlobal);
+ doReturn(display).when(displayManagerGlobal).getCompatibleDisplay(eq(displayId),
+ (Resources) any());
}
@Test
@@ -60,9 +98,9 @@ public class InputMethodMenuControllerTest extends WindowTestsBase {
// Obtain the context again and check they are the same instance and match the display
// metrics of the secondary display.
final Context contextOnSecondaryDisplay = mController.getSettingsContext(
- mDisplayContent.getDisplayId());
+ mSecondaryDisplay.getDisplayId());
- assertImeSwitchContextMetricsValidity(contextOnSecondaryDisplay, mDisplayContent);
+ assertImeSwitchContextMetricsValidity(contextOnSecondaryDisplay, mSecondaryDisplay);
assertThat(contextOnDefaultDisplay.getWindowContextToken())
.isEqualTo(contextOnSecondaryDisplay.getWindowContextToken());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
index e514ac04efbe..cd428e10a437 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
@@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
@@ -92,11 +93,12 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final ActivityRecord source = new ActivityBuilder(mAtm).build();
final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0);
final ActivityOptions options = mock(ActivityOptions.class);
+ final Request request = new Request();
mController.calculate(record.getTask(), layout, record, source, options, PHASE_BOUNDS,
- new LaunchParams());
+ new LaunchParams(), request);
verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record),
- eq(source), eq(options), anyInt(), any(), any());
+ eq(source), eq(options), anyInt(), any(), any(), eq(request));
}
/**
@@ -119,9 +121,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mPersister.putLaunchParams(userId, name, expected);
mController.calculate(activity.getTask(), null /*layout*/, activity, null /*source*/,
- null /*options*/, PHASE_BOUNDS, new LaunchParams());
+ null /*options*/, PHASE_BOUNDS, new LaunchParams(), null /* request */);
verify(positioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
- eq(expected), any());
+ eq(expected), any(), any());
}
/**
@@ -132,16 +134,17 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final LaunchParamsModifier
ignoredPositioner = mock(LaunchParamsModifier.class);
final LaunchParamsModifier earlyExitPositioner =
- (task, layout, activity, source, options, phase, currentParams, outParams)
+ (task, layout, activity, source, options, phase, currentParams, outParams, request)
-> RESULT_DONE;
mController.registerModifier(ignoredPositioner);
mController.registerModifier(earlyExitPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
- null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams());
+ null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(),
+ null /* request */);
verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(), anyInt(),
- any(), any());
+ any(), any(), any());
}
/**
@@ -157,20 +160,22 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mController.registerModifier(firstPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
- null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams());
+ null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(),
+ null /* request */);
verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
- any(), any());
+ any(), any(), any());
final LaunchParamsModifier secondPositioner = spy(earlyExitPositioner);
mController.registerModifier(secondPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
- null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams());
+ null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(),
+ null /* request */);
verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
- any(), any());
+ any(), any(), any());
verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
- any(), any());
+ any(), any(), any());
}
/**
@@ -192,10 +197,10 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mController.registerModifier(positioner2);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
- null /*options*/, PHASE_BOUNDS, new LaunchParams());
+ null /*options*/, PHASE_BOUNDS, new LaunchParams(), null /* request */);
verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(),
- eq(positioner2.getLaunchParams()), any());
+ eq(positioner2.getLaunchParams()), any(), any());
}
/**
@@ -218,7 +223,7 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final LaunchParams result = new LaunchParams();
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
- null /*options*/, PHASE_BOUNDS, result);
+ null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(result, positioner2.getLaunchParams());
}
@@ -237,17 +242,17 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
// VR activities should always land on default display.
mController.calculate(null /*task*/, null /*layout*/, vrActivity /*activity*/,
- null /*source*/, null /*options*/, PHASE_BOUNDS, result);
+ null /*source*/, null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(),
result.mPreferredTaskDisplayArea);
// Otherwise, always lands on VR 2D display.
final ActivityRecord vr2dActivity = new ActivityBuilder(mAtm).build();
mController.calculate(null /*task*/, null /*layout*/, vr2dActivity /*activity*/,
- null /*source*/, null /*options*/, PHASE_BOUNDS, result);
+ null /*source*/, null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
- null /*options*/, PHASE_BOUNDS, result);
+ null /*options*/, PHASE_BOUNDS, result, null /* request */);
assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea);
mAtm.mVr2dDisplayId = INVALID_DISPLAY;
@@ -269,9 +274,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
final ActivityOptions options = mock(ActivityOptions.class);
mController.calculate(record.getTask(), layout, record, source, options, PHASE_BOUNDS,
- new LaunchParams());
+ new LaunchParams(), null /* request */);
verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record),
- eq(source), eq(options), eq(PHASE_BOUNDS), any(), any());
+ eq(source), eq(options), eq(PHASE_BOUNDS), any(), any(), any());
}
/**
@@ -403,8 +408,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
@Override
public int onCalculate(Task task, WindowLayout layout, ActivityRecord activity,
- ActivityRecord source, ActivityOptions options, int phase,
- LaunchParams currentParams, LaunchParams outParams) {
+ ActivityRecord source, ActivityOptions options, int phase,
+ LaunchParams currentParams, LaunchParams outParams,
+ Request request) {
outParams.set(mParams);
return mReturnVal;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
deleted file mode 100644
index 25ba6db38e05..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ /dev/null
@@ -1,382 +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.wm;
-
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.graphics.Color.RED;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Gravity.BOTTOM;
-import static android.view.Gravity.LEFT;
-import static android.view.Gravity.RIGHT;
-import static android.view.Gravity.TOP;
-import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.VirtualDisplay;
-import android.media.ImageReader;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.platform.test.annotations.Presubmit;
-import android.util.Pair;
-import android.view.Display;
-import android.view.DisplayInfo;
-import android.view.View;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.widget.TextView;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.compatibility.common.util.SystemUtil;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.function.BooleanSupplier;
-
-/**
- * Tests for the {@link android.view.WindowManager.LayoutParams#PRIVATE_FLAG_IS_SCREEN_DECOR} flag.
- *
- * Build/Install/Run:
- * atest WmTests:ScreenDecorWindowTests
- */
-// TODO: Add test for FLAG_FULLSCREEN which hides the status bar and also other flags.
-// TODO: Test non-Activity windows.
-@SmallTest
-@Presubmit
-public class ScreenDecorWindowTests {
-
- private final Context mContext = getInstrumentation().getTargetContext();
- private final Instrumentation mInstrumentation = getInstrumentation();
-
- private WindowManager mWm;
- private ArrayList<View> mWindows = new ArrayList<>();
-
- private Activity mTestActivity;
- private VirtualDisplay mDisplay;
- private ImageReader mImageReader;
-
- private int mDecorThickness;
- private int mHalfDecorThickness;
-
- @Before
- public void setUp() {
- final Pair<VirtualDisplay, ImageReader> result = createDisplay();
- mDisplay = result.first;
- mImageReader = result.second;
- final Display display = mDisplay.getDisplay();
- final Context dContext = mContext.createDisplayContext(display);
- mWm = dContext.getSystemService(WindowManager.class);
- mTestActivity = startActivityOnDisplay(TestActivity.class, display.getDisplayId());
- final Point size = new Point();
- mDisplay.getDisplay().getRealSize(size);
- mDecorThickness = Math.min(size.x, size.y) / 3;
- mHalfDecorThickness = mDecorThickness / 2;
- }
-
- @After
- public void tearDown() {
- while (!mWindows.isEmpty()) {
- removeWindow(mWindows.get(0));
- }
- finishActivity(mTestActivity);
- mDisplay.release();
- mImageReader.close();
- }
-
- @Test
- public void testScreenSides() {
- // Decor on top
- final View decorWindow = createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
- assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
-
- // Decor at the bottom
- updateWindow(decorWindow, BOTTOM, MATCH_PARENT, mDecorThickness, 0, 0);
- assertInsetGreaterOrEqual(mTestActivity, BOTTOM, mDecorThickness);
-
- // Decor to the left
- updateWindow(decorWindow, LEFT, mDecorThickness, MATCH_PARENT, 0, 0);
- assertInsetGreaterOrEqual(mTestActivity, LEFT, mDecorThickness);
-
- // Decor to the right
- updateWindow(decorWindow, RIGHT, mDecorThickness, MATCH_PARENT, 0, 0);
- assertInsetGreaterOrEqual(mTestActivity, RIGHT, mDecorThickness);
- }
-
- // Decor windows (i.e windows using PRIVATE_FLAG_IS_SCREEN_DECOR) are no longer supported.
- // PRIVATE_FLAG_IS_SCREEN_DECOR and related code will be deprecated/removed soon.
- @Ignore
- @Test
- public void testMultipleDecors() {
- // Test 2 decor windows on-top.
- createDecorWindow(TOP, MATCH_PARENT, mHalfDecorThickness);
- assertInsetGreaterOrEqual(mTestActivity, TOP, mHalfDecorThickness);
- createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
- assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
-
- // And one at the bottom.
- createDecorWindow(BOTTOM, MATCH_PARENT, mHalfDecorThickness);
- assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
- assertInsetGreaterOrEqual(mTestActivity, BOTTOM, mHalfDecorThickness);
- }
-
- @Test
- public void testFlagChange() {
- WindowInsets initialInsets = getInsets(mTestActivity);
-
- final View decorWindow = createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
- assertTopInsetEquals(mTestActivity, mDecorThickness);
-
- updateWindow(decorWindow, TOP, MATCH_PARENT, mDecorThickness,
- 0, PRIVATE_FLAG_IS_SCREEN_DECOR);
-
- // TODO: fix test and re-enable assertion.
- // initialInsets was not actually immutable and just updated to the current insets,
- // meaning this assertion never actually tested anything. Now that WindowInsets actually is
- // immutable, it turns out the test was broken.
- // assertTopInsetEquals(mTestActivity, initialInsets.getSystemWindowInsetTop());
-
- updateWindow(decorWindow, TOP, MATCH_PARENT, mDecorThickness,
- PRIVATE_FLAG_IS_SCREEN_DECOR, PRIVATE_FLAG_IS_SCREEN_DECOR);
- assertTopInsetEquals(mTestActivity, mDecorThickness);
- }
-
- @Test
- public void testRemoval() {
- WindowInsets initialInsets = getInsets(mTestActivity);
-
- final View decorWindow = createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
- assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
-
- removeWindow(decorWindow);
- assertTopInsetEquals(mTestActivity, initialInsets.getSystemWindowInsetTop());
- }
-
- @Test
- public void testProvidesInsetsTypes() {
- int[] providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR};
- final View win = createWindow("StatusBarSubPanel", TOP, MATCH_PARENT, mDecorThickness, RED,
- FLAG_LAYOUT_IN_SCREEN, 0, providesInsetsTypes);
-
- assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
- }
-
- private View createDecorWindow(int gravity, int width, int height) {
- int[] providesInsetsTypes =
- new int[]{gravity == TOP ? ITYPE_CLIMATE_BAR : ITYPE_EXTRA_NAVIGATION_BAR};
- return createWindow("decorWindow", gravity, width, height, RED,
- FLAG_LAYOUT_IN_SCREEN, PRIVATE_FLAG_IS_SCREEN_DECOR, providesInsetsTypes);
- }
-
- private View createWindow(String name, int gravity, int width, int height, int color, int flags,
- int privateFlags, int[] providesInsetsTypes) {
-
- final View[] viewHolder = new View[1];
- final int finalFlag = flags
- | FLAG_NOT_FOCUSABLE | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_NOT_TOUCHABLE;
-
- // Needs to run on the UI thread.
- Handler.getMain().runWithScissors(() -> {
- final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- width, height, TYPE_APPLICATION_OVERLAY, finalFlag, PixelFormat.OPAQUE);
- lp.gravity = gravity;
- lp.privateFlags |= privateFlags;
- lp.providesInsetsTypes = providesInsetsTypes;
-
- final TextView view = new TextView(mContext);
- view.setText("ScreenDecorWindowTests - " + name);
- view.setBackgroundColor(color);
- mWm.addView(view, lp);
- mWindows.add(view);
- viewHolder[0] = view;
- }, 0);
-
- waitForIdle();
- return viewHolder[0];
- }
-
- private void updateWindow(View v, int gravity, int width, int height,
- int privateFlags, int privateFlagsMask) {
- // Needs to run on the UI thread.
- Handler.getMain().runWithScissors(() -> {
- final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) v.getLayoutParams();
- lp.gravity = gravity;
- lp.width = width;
- lp.height = height;
- setPrivateFlags(lp, privateFlags, privateFlagsMask);
-
- mWm.updateViewLayout(v, lp);
- }, 0);
-
- waitForIdle();
- }
-
- private void removeWindow(View v) {
- Handler.getMain().runWithScissors(() -> mWm.removeView(v), 0);
- mWindows.remove(v);
- waitForIdle();
- }
-
- private WindowInsets getInsets(Activity a) {
- return new WindowInsets(a.getWindow().getDecorView().getRootWindowInsets());
- }
-
- /**
- * Set the flags of the window, as per the
- * {@link WindowManager.LayoutParams WindowManager.LayoutParams}
- * flags.
- *
- * @param flags The new window flags (see WindowManager.LayoutParams).
- * @param mask Which of the window flag bits to modify.
- */
- public void setPrivateFlags(WindowManager.LayoutParams lp, int flags, int mask) {
- lp.flags = (lp.flags & ~mask) | (flags & mask);
- }
-
- /**
- * Asserts the top inset of {@param activity} is equal to {@param expected} waiting as needed.
- */
- private void assertTopInsetEquals(Activity activity, int expected) {
- waitForTopInsetEqual(activity, expected);
- assertEquals(expected, getInsets(activity).getSystemWindowInsetTop());
- }
-
- private void waitForTopInsetEqual(Activity activity, int expected) {
- waitFor(() -> getInsets(activity).getSystemWindowInsetTop() == expected);
- }
-
- /**
- * Asserts the inset at {@param side} of {@param activity} is equal to {@param expected}
- * waiting as needed.
- */
- private void assertInsetGreaterOrEqual(Activity activity, int side, int expected) {
- waitForInsetGreaterOrEqual(activity, side, expected);
-
- final WindowInsets insets = getInsets(activity);
- switch (side) {
- case TOP:
- assertThat(insets.getSystemWindowInsetTop()).isAtLeast(expected);
- break;
- case BOTTOM:
- assertThat(insets.getSystemWindowInsetBottom()).isAtLeast(expected);
- break;
- case LEFT:
- assertThat(insets.getSystemWindowInsetLeft()).isAtLeast(expected);
- break;
- case RIGHT:
- assertThat(insets.getSystemWindowInsetRight()).isAtLeast(expected);
- break;
- }
- }
-
- private void waitForInsetGreaterOrEqual(Activity activity, int side, int expected) {
- waitFor(() -> {
- final WindowInsets insets = getInsets(activity);
- switch (side) {
- case TOP: return insets.getSystemWindowInsetTop() >= expected;
- case BOTTOM: return insets.getSystemWindowInsetBottom() >= expected;
- case LEFT: return insets.getSystemWindowInsetLeft() >= expected;
- case RIGHT: return insets.getSystemWindowInsetRight() >= expected;
- default: return true;
- }
- });
- }
-
- private void waitFor(BooleanSupplier waitCondition) {
- int retriesLeft = 5;
- do {
- if (waitCondition.getAsBoolean()) {
- break;
- }
- SystemClock.sleep(500);
- } while (retriesLeft-- > 0);
- }
-
- private void finishActivity(Activity a) {
- if (a == null) {
- return;
- }
- a.finish();
- waitForIdle();
- }
-
- private void waitForIdle() {
- mInstrumentation.waitForIdleSync();
- }
-
- private Activity startActivityOnDisplay(Class<?> cls, int displayId) {
- final Intent intent = new Intent(mContext, cls);
- intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
- final ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchDisplayId(displayId);
-
- final Activity activity = SystemUtil.runWithShellPermissionIdentity(
- () -> mInstrumentation.startActivitySync(intent, options.toBundle()),
- "android.permission.ACTIVITY_EMBEDDING");
- waitForIdle();
-
- assertEquals(displayId, activity.getDisplayId());
- return activity;
- }
-
- private Pair<VirtualDisplay, ImageReader> createDisplay() {
- final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
- final DisplayInfo displayInfo = new DisplayInfo();
- final Display defaultDisplay = dm.getDisplay(DEFAULT_DISPLAY);
- defaultDisplay.getDisplayInfo(displayInfo);
- final String name = "ScreenDecorWindowTests";
- int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
-
- final ImageReader imageReader = ImageReader.newInstance(
- displayInfo.logicalWidth, displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);
-
- final VirtualDisplay display = dm.createVirtualDisplay(name, displayInfo.logicalWidth,
- displayInfo.logicalHeight, displayInfo.logicalDensityDpi, imageReader.getSurface(),
- flags);
-
- return Pair.create(display, imageReader);
- }
-
- public static class TestActivity extends Activity {
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 98520bb7a20b..4f55322e2085 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -35,6 +35,7 @@ import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.ActivityStarter.Request;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
@@ -42,6 +43,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
@@ -265,6 +269,180 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
mResult.mPreferredTaskDisplayArea);
}
+ @Test
+ public void testUsesDisplayAreaFromTopMostActivityInApplicationIfAvailable() {
+ final String processName = "processName";
+ final int uid = 124214;
+ final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TaskDisplayArea expectedDisplayArea = secondScreen.getDefaultTaskDisplayArea();
+ final WindowProcessController controller = mock(WindowProcessController.class);
+
+ when(controller.getTopActivityDisplayArea()).thenReturn(expectedDisplayArea);
+
+ when(mActivity.getProcessName()).thenReturn(processName);
+ when(mActivity.getUid()).thenReturn(uid);
+ doReturn(controller)
+ .when(mSupervisor.mService)
+ .getProcessController(processName, uid);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
+ null /* task */,
+ null /* layout */,
+ mActivity /* activity */,
+ null /* source */,
+ null /* options */,
+ -1 /* phase */,
+ mCurrent,
+ mResult,
+ null /* request */
+ ));
+
+ assertEquals(expectedDisplayArea, mResult.mPreferredTaskDisplayArea);
+ }
+
+ @Test
+ public void testUsesDisplayAreaFromLaunchingActivityIfApplicationLaunching() {
+ final String processName = "processName";
+ final int uid = 124214;
+ final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea();
+ final WindowProcessController controller = mock(WindowProcessController.class);
+
+ when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea);
+
+ when(mActivity.getProcessName()).thenReturn(processName);
+ when(mActivity.getUid()).thenReturn(uid);
+ doReturn(null)
+ .when(mSupervisor.mService)
+ .getProcessController(processName, uid);
+
+ doReturn(controller)
+ .when(mSupervisor.mService)
+ .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
+ null /* task */,
+ null /* layout */,
+ mActivity /* activity */,
+ null /* source */,
+ null /* options */,
+ -1 /* phase */,
+ mCurrent,
+ mResult,
+ null /* request */
+ ));
+
+ assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
+ }
+
+ @Test
+ public void testDisplayAreaFromLaunchingActivityTakesPrecedence() {
+ final String processName = "processName";
+ final int uid = 124214;
+ final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TaskDisplayArea firstTaskDisplayArea = firstScreen.getDefaultTaskDisplayArea();
+ final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea();
+ final WindowProcessController controllerForLaunching = mock(WindowProcessController.class);
+ final WindowProcessController controllerForApplication =
+ mock(WindowProcessController.class);
+
+ when(mActivity.getProcessName()).thenReturn(processName);
+ when(mActivity.getUid()).thenReturn(uid);
+
+ when(controllerForApplication.getTopActivityDisplayArea()).thenReturn(firstTaskDisplayArea);
+ when(controllerForLaunching.getTopActivityDisplayArea())
+ .thenReturn(expectedTaskDisplayArea);
+
+ doReturn(controllerForApplication)
+ .when(mSupervisor.mService)
+ .getProcessController(processName, uid);
+ doReturn(controllerForLaunching)
+ .when(mSupervisor.mService)
+ .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
+ null /* task */,
+ null /* layout */,
+ mActivity /* activity */,
+ null /* source */,
+ null /* options */,
+ -1 /* phase */,
+ mCurrent,
+ mResult,
+ null /* request */
+ ));
+
+ assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
+ }
+
+ @Test
+ public void testUsesDisplayAreaOriginalProcessAsLastResort() {
+ final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+ final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea();
+ final Request request = new Request();
+ request.realCallingPid = 12412413;
+ request.realCallingUid = 235424;
+
+ final WindowProcessController controller = mock(WindowProcessController.class);
+
+ when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea);
+
+ doReturn(null)
+ .when(mSupervisor.mService)
+ .getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid);
+
+ doReturn(null)
+ .when(mSupervisor.mService)
+ .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
+
+ doReturn(controller)
+ .when(mSupervisor.mService)
+ .getProcessController(request.realCallingPid, request.realCallingUid);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
+ null /* task */,
+ null /* layout */,
+ mActivity /* activity */,
+ null /* source */,
+ null /* options */,
+ -1 /* phase */,
+ mCurrent,
+ mResult,
+ request
+ ));
+
+ assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
+ }
+
+ @Test
+ public void testUsesDefaultDisplayAreaIfWindowProcessControllerIsNotPresent() {
+ doReturn(null)
+ .when(mSupervisor.mService)
+ .getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid);
+
+ doReturn(null)
+ .when(mSupervisor.mService)
+ .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(
+ null /* task */,
+ null /* layout */,
+ mActivity /* activity */,
+ null /* source */,
+ null /* options */,
+ -1 /* phase */,
+ mCurrent,
+ mResult,
+ null /* request */
+ ));
+
+ assertEquals(DEFAULT_DISPLAY, mResult.mPreferredTaskDisplayArea.getDisplayId());
+ }
+
// =====================================
// Launch Windowing Mode Related Tests
// =====================================
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 165d4681c9e0..4909b1d7629e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.window.TransitionInfo.TRANSIT_HIDE;
@@ -46,16 +47,24 @@ import org.junit.runner.RunWith;
@RunWith(WindowTestRunner.class)
public class TransitionTests extends WindowTestsBase {
+ private Transition createTestTransition(int transitType) {
+ TransitionController controller = mock(TransitionController.class);
+ BLASTSyncEngine sync = new BLASTSyncEngine(mWm);
+ return new Transition(transitType, 0 /* flags */, controller, sync);
+ }
+
@Test
public void testCreateInfo_NewTask() {
+ final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
+ ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+ ArraySet<WindowContainer> participants = transition.mParticipants;
+
final Task newTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
final Task oldTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
final ActivityRecord closing = createActivityRecord(oldTask);
final ActivityRecord opening = createActivityRecord(newTask);
- ArrayMap<WindowContainer, Transition.ChangeInfo> changes = new ArrayMap<>();
- ArraySet<WindowContainer> participants = new ArraySet();
// Start states.
changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
changes.put(oldTask, new Transition.ChangeInfo(true /* vis */, true /* exChg */));
@@ -70,29 +79,32 @@ public class TransitionTests extends WindowTestsBase {
// Check basic both tasks participating
participants.add(oldTask);
participants.add(newTask);
- TransitionInfo info =
- Transition.calculateTransitionInfo(transitType, participants, changes);
+ ArraySet<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+ TransitionInfo info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertEquals(transitType, info.getType());
// Check that children are pruned
participants.add(opening);
participants.add(closing);
- info = Transition.calculateTransitionInfo(transitType, participants, changes);
+ targets = Transition.calculateTargets(participants, changes);
+ info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
// Check combined prune and promote
participants.remove(newTask);
- info = Transition.calculateTransitionInfo(transitType, participants, changes);
+ targets = Transition.calculateTargets(participants, changes);
+ info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
// Check multi promote
participants.remove(oldTask);
- info = Transition.calculateTransitionInfo(transitType, participants, changes);
+ targets = Transition.calculateTargets(participants, changes);
+ info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -100,6 +112,10 @@ public class TransitionTests extends WindowTestsBase {
@Test
public void testCreateInfo_NestedTasks() {
+ final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
+ ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+ ArraySet<WindowContainer> participants = transition.mParticipants;
+
final Task newTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
final Task newNestedTask = createTaskInStack(newTask, 0);
@@ -109,8 +125,6 @@ public class TransitionTests extends WindowTestsBase {
final ActivityRecord closing = createActivityRecord(oldTask);
final ActivityRecord opening = createActivityRecord(newNestedTask);
final ActivityRecord opening2 = createActivityRecord(newNestedTask2);
- ArrayMap<WindowContainer, Transition.ChangeInfo> changes = new ArrayMap<>();
- ArraySet<WindowContainer> participants = new ArraySet();
// Start states.
changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
changes.put(newNestedTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
@@ -130,8 +144,8 @@ public class TransitionTests extends WindowTestsBase {
participants.add(oldTask);
participants.add(opening);
participants.add(opening2);
- TransitionInfo info =
- Transition.calculateTransitionInfo(transitType, participants, changes);
+ ArraySet<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+ TransitionInfo info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertEquals(transitType, info.getType());
assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
@@ -139,7 +153,8 @@ public class TransitionTests extends WindowTestsBase {
// Check that unchanging but visible descendant of sibling prevents promotion
participants.remove(opening2);
- info = Transition.calculateTransitionInfo(transitType, participants, changes);
+ targets = Transition.calculateTargets(participants, changes);
+ info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertNotNull(info.getChange(newNestedTask.mRemoteToken.toWindowContainerToken()));
assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -147,6 +162,9 @@ public class TransitionTests extends WindowTestsBase {
@Test
public void testCreateInfo_DisplayArea() {
+ final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
+ ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+ ArraySet<WindowContainer> participants = transition.mParticipants;
final Task showTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
final Task showNestedTask = createTaskInStack(showTask, 0);
@@ -155,8 +173,6 @@ public class TransitionTests extends WindowTestsBase {
final DisplayArea tda = showTask.getDisplayArea();
final ActivityRecord showing = createActivityRecord(showNestedTask);
final ActivityRecord showing2 = createActivityRecord(showTask2);
- ArrayMap<WindowContainer, Transition.ChangeInfo> changes = new ArrayMap<>();
- ArraySet<WindowContainer> participants = new ArraySet();
// Start states.
changes.put(showTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
changes.put(showNestedTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
@@ -173,8 +189,8 @@ public class TransitionTests extends WindowTestsBase {
// Check promotion to DisplayArea
participants.add(showing);
participants.add(showing2);
- TransitionInfo info =
- Transition.calculateTransitionInfo(transitType, participants, changes);
+ ArraySet<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+ TransitionInfo info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(1, info.getChanges().size());
assertEquals(transitType, info.getType());
assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken()));
@@ -182,22 +198,21 @@ public class TransitionTests extends WindowTestsBase {
ITaskOrganizer mockOrg = mock(ITaskOrganizer.class);
// Check that organized tasks get reported even if not top
showTask.mTaskOrganizer = mockOrg;
- info = Transition.calculateTransitionInfo(transitType, participants, changes);
+ targets = Transition.calculateTargets(participants, changes);
+ info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken()));
assertNotNull(info.getChange(showTask.mRemoteToken.toWindowContainerToken()));
// Even if DisplayArea explicitly participating
participants.add(tda);
- info = Transition.calculateTransitionInfo(transitType, participants, changes);
+ targets = Transition.calculateTargets(participants, changes);
+ info = Transition.calculateTransitionInfo(transitType, targets, changes);
assertEquals(2, info.getChanges().size());
}
@Test
public void testCreateInfo_existenceChange() {
- TransitionController controller = mock(TransitionController.class);
- BLASTSyncEngine sync = new BLASTSyncEngine(mWm);
- Transition transition = new Transition(
- TRANSIT_OLD_TASK_OPEN, 0 /* flags */, controller, sync);
+ final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
final Task openTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
@@ -214,8 +229,9 @@ public class TransitionTests extends WindowTestsBase {
opening.mVisibleRequested = true;
closing.mVisibleRequested = false;
- TransitionInfo info = Transition.calculateTransitionInfo(
- 0, transition.mParticipants, transition.mChanges);
+ ArraySet<WindowContainer> targets = Transition.calculateTargets(
+ transition.mParticipants, transition.mChanges);
+ TransitionInfo info = Transition.calculateTransitionInfo(0, targets, transition.mChanges);
assertEquals(2, info.getChanges().size());
// There was an existence change on open, so it should be OPEN rather than SHOW
assertEquals(TRANSIT_OPEN,
@@ -224,4 +240,39 @@ public class TransitionTests extends WindowTestsBase {
assertEquals(TRANSIT_HIDE,
info.getChange(closeTask.mRemoteToken.toWindowContainerToken()).getMode());
}
+
+ @Test
+ public void testCreateInfo_ordering() {
+ final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN);
+ // pick some number with a high enough chance of being out-of-order when added to set.
+ final int taskCount = 6;
+
+ final Task[] tasks = new Task[taskCount];
+ for (int i = 0; i < taskCount; ++i) {
+ // Each add goes on top, so at the end of this, task[9] should be on top
+ tasks[i] = createTaskStackOnDisplay(WINDOWING_MODE_FREEFORM,
+ ACTIVITY_TYPE_STANDARD, mDisplayContent);
+ final ActivityRecord act = createActivityRecord(tasks[i]);
+ // alternate so that the transition doesn't get promoted to the display area
+ act.mVisibleRequested = (i % 2) == 0; // starts invisible
+ }
+
+ // doesn't matter which order collected since participants is a set
+ for (int i = 0; i < taskCount; ++i) {
+ transition.collectExistenceChange(tasks[i]);
+ final ActivityRecord act = tasks[i].getTopMostActivity();
+ transition.collect(act);
+ tasks[i].getTopMostActivity().mVisibleRequested = (i % 2) != 0;
+ }
+
+ ArraySet<WindowContainer> targets = Transition.calculateTargets(
+ transition.mParticipants, transition.mChanges);
+ TransitionInfo info = Transition.calculateTransitionInfo(0, targets, transition.mChanges);
+ assertEquals(taskCount, info.getChanges().size());
+ // verify order is top-to-bottem
+ for (int i = 0; i < taskCount; ++i) {
+ assertEquals(tasks[taskCount - i - 1].mRemoteToken.toWindowContainerToken(),
+ info.getChanges().get(i).getContainer());
+ }
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 5afcedb10dd6..3057558a6e98 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -27,10 +27,13 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.IApplicationThread;
@@ -327,6 +330,45 @@ public class WindowProcessControllerTests extends WindowTestsBase {
return new ActivityBuilder(mAtm).setCreateTask(true).setUseProcess(wpc).build();
}
+ @Test
+ public void testTopActivityDisplayAreaMatchesTopMostActivity_noActivities() {
+ assertNull(mWpc.getTopActivityDisplayArea());
+ }
+
+ @Test
+ public void testTopActivityDisplayAreaMatchesTopMostActivity_singleActivity() {
+ final ActivityRecord activityRecord = new ActivityBuilder(mSupervisor.mService).build();
+ final TaskDisplayArea expectedDisplayArea = mock(TaskDisplayArea.class);
+
+ when(activityRecord.getDisplayArea())
+ .thenReturn(expectedDisplayArea);
+
+ mWpc.addActivityIfNeeded(activityRecord);
+
+ assertEquals(expectedDisplayArea, mWpc.getTopActivityDisplayArea());
+ }
+
+ /**
+ * Test that top most activity respects z-order.
+ */
+ @Test
+ public void testTopActivityDisplayAreaMatchesTopMostActivity_multipleActivities() {
+ final ActivityRecord bottomRecord = new ActivityBuilder(mSupervisor.mService).build();
+ final TaskDisplayArea bottomDisplayArea = mock(TaskDisplayArea.class);
+ final ActivityRecord topRecord = new ActivityBuilder(mSupervisor.mService).build();
+ final TaskDisplayArea topDisplayArea = mock(TaskDisplayArea.class);
+
+ when(bottomRecord.getDisplayArea()).thenReturn(bottomDisplayArea);
+ when(topRecord.getDisplayArea()).thenReturn(topDisplayArea);
+ doReturn(-1).when(bottomRecord).compareTo(topRecord);
+ doReturn(1).when(topRecord).compareTo(bottomRecord);
+
+ mWpc.addActivityIfNeeded(topRecord);
+ mWpc.addActivityIfNeeded(bottomRecord);
+
+ assertEquals(topDisplayArea, mWpc.getTopActivityDisplayArea());
+ }
+
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 1d498bd3253b..227eba2a041b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -648,6 +648,8 @@ public class WindowStateTests extends WindowTestsBase {
win1.mSurfaceControl = mock(SurfaceControl.class);
win1.mAttrs.surfaceInsets.set(1, 2, 3, 4);
win1.getFrame().offsetTo(WINDOW_OFFSET, 0);
+ // Simulate layout
+ win1.mRelayoutCalled = true;
win1.updateSurfacePosition(t);
win1.getTransformationMatrix(values, matrix);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 83053813116b..6c046bda1444 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -40,6 +40,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -80,6 +82,7 @@ import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.view.WindowManager;
+import android.view.WindowManager.DisplayImePolicy;
import android.window.ITaskOrganizer;
import com.android.internal.util.ArrayUtils;
@@ -174,7 +177,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
private void createTestDisplay(UseTestDisplay annotation) {
beforeCreateTestDisplay();
- mDisplayContent = createNewDisplay(true /* supportIme */);
+ mDisplayContent = createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
final boolean addAll = annotation.addAllCommonWindows();
final @CommonTypes int[] requestedWindows = annotation.addWindows();
@@ -482,26 +485,26 @@ class WindowTestsBase extends SystemServiceTestsBase {
/** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
DisplayContent createNewDisplay() {
- return createNewDisplay(true /* supportIme */);
+ return createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL);
}
/** Creates a {@link DisplayContent} and adds it to the system. */
- private DisplayContent createNewDisplay(boolean supportIme) {
- return createNewDisplay(mDisplayInfo, supportIme);
+ private DisplayContent createNewDisplayWithImeSupport(@DisplayImePolicy int imePolicy) {
+ return createNewDisplay(mDisplayInfo, imePolicy);
}
/** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
DisplayContent createNewDisplay(DisplayInfo info) {
- return createNewDisplay(info, true /* supportIme */);
+ return createNewDisplay(info, DISPLAY_IME_POLICY_LOCAL);
}
/** Creates a {@link DisplayContent} and adds it to the system. */
- private DisplayContent createNewDisplay(DisplayInfo info, boolean supportIme) {
+ private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) {
final DisplayContent display =
new TestDisplayContent.Builder(mAtm, info).build();
final DisplayContent dc = display.mDisplayContent;
// this display can show IME.
- dc.mWmService.mDisplayWindowSettings.setShouldShowImeLocked(dc, supportIme);
+ dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
return dc;
}
@@ -516,7 +519,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
DisplayInfo displayInfo = new DisplayInfo();
displayInfo.copyFrom(mDisplayInfo);
displayInfo.state = displayState;
- return createNewDisplay(displayInfo, true /* supportIme */);
+ return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_LOCAL);
}
/** Creates a {@link TestWindowState} */
@@ -532,7 +535,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
displayInfo.copyFrom(mDisplayInfo);
displayInfo.type = Display.TYPE_VIRTUAL;
displayInfo.ownerUid = SYSTEM_UID;
- return createNewDisplay(displayInfo, false /* supportIme */);
+ return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY);
}
IDisplayWindowInsetsController createDisplayWindowInsetsController() {
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 5024ae27ee49..835ecaa8c90d 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -361,7 +361,13 @@ public final class PhoneAccount implements Parcelable {
*/
public static final int CAPABILITY_ADHOC_CONFERENCE_CALLING = 0x4000;
- /* NEXT CAPABILITY: 0x8000 */
+ /**
+ * Flag indicating whether this {@link PhoneAccount} is capable of supporting the call composer
+ * functionality for enriched calls.
+ */
+ public static final int CAPABILITY_CALL_COMPOSER = 0x8000;
+
+ /* NEXT CAPABILITY: 0x10000 */
/**
* URI scheme for telephone number URIs.
@@ -1088,6 +1094,9 @@ public final class PhoneAccount implements Parcelable {
if (hasCapabilities(CAPABILITY_ADHOC_CONFERENCE_CALLING)) {
sb.append("AdhocConf");
}
+ if (hasCapabilities(CAPABILITY_CALL_COMPOSER)) {
+ sb.append("CallComposer ");
+ }
return sb.toString();
}
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index ada069666547..8d7742b7510b 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -76,39 +76,46 @@ public class RcsUceAdapter {
* @hide
*/
public static final int ERROR_GENERIC_FAILURE = 1;
+
/**
* The carrier network does not have UCE support enabled for this subscriber.
* @hide
*/
public static final int ERROR_NOT_ENABLED = 2;
+
/**
* The data network that the device is connected to does not support UCE currently (e.g. it is
* 1x only currently).
* @hide
*/
public static final int ERROR_NOT_AVAILABLE = 3;
+
/**
* The network has responded with SIP 403 error and a reason "User not registered."
* @hide
*/
public static final int ERROR_NOT_REGISTERED = 4;
+
/**
* The network has responded to this request with a SIP 403 error and reason "not authorized for
* presence" for this subscriber.
* @hide
*/
public static final int ERROR_NOT_AUTHORIZED = 5;
+
/**
* The network has responded to this request with a SIP 403 error and no reason.
* @hide
*/
public static final int ERROR_FORBIDDEN = 6;
+
/**
* The contact URI requested is not provisioned for VoLTE or it is not known as an IMS
* subscriber to the carrier network.
* @hide
*/
public static final int ERROR_NOT_FOUND = 7;
+
/**
* The capabilities request contained too many URIs for the carrier network to handle. Retry
* with a lower number of contact numbers. The number varies per carrier.
@@ -116,22 +123,32 @@ public class RcsUceAdapter {
*/
// TODO: Try to integrate this into the API so that the service will split based on carrier.
public static final int ERROR_REQUEST_TOO_LARGE = 8;
+
/**
* The network did not respond to the capabilities request before the request timed out.
* @hide
*/
public static final int ERROR_REQUEST_TIMEOUT = 10;
+
/**
* The request failed due to the service having insufficient memory.
* @hide
*/
public static final int ERROR_INSUFFICIENT_MEMORY = 11;
+
/**
* The network was lost while trying to complete the request.
* @hide
*/
public static final int ERROR_LOST_NETWORK = 12;
+ /**
+ * The network is temporarily unavailable or busy. Retries should only be done after the retry
+ * time returned in {@link CapabilitiesCallback#onError} has elapsed.
+ * @hide
+ */
+ public static final int ERROR_SERVER_UNAVAILABLE = 13;
+
/**@hide*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "ERROR_", value = {
@@ -145,7 +162,8 @@ public class RcsUceAdapter {
ERROR_REQUEST_TOO_LARGE,
ERROR_REQUEST_TIMEOUT,
ERROR_INSUFFICIENT_MEMORY,
- ERROR_LOST_NETWORK
+ ERROR_LOST_NETWORK,
+ ERROR_SERVER_UNAVAILABLE
})
public @interface ErrorCode {}
@@ -369,8 +387,10 @@ public class RcsUceAdapter {
* The pending request has resulted in an error and may need to be retried, depending on the
* error code.
* @param errorCode The reason for the framework being unable to process the request.
+ * @param retryAfterMilliseconds The time in milliseconds the requesting application should
+ * wait before retrying, if non-zero.
*/
- void onError(@ErrorCode int errorCode);
+ void onError(@ErrorCode int errorCode, long retryAfterMilliseconds);
}
private final Context mContext;
@@ -451,10 +471,10 @@ public class RcsUceAdapter {
}
}
@Override
- public void onError(int errorCode) {
+ public void onError(int errorCode, long retryAfterMilliseconds) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
- executor.execute(() -> c.onError(errorCode));
+ executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
} finally {
restoreCallingIdentity(callingIdentity);
}
@@ -535,10 +555,10 @@ public class RcsUceAdapter {
}
}
@Override
- public void onError(int errorCode) {
+ public void onError(int errorCode, long retryAfterMilliseconds) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
- executor.execute(() -> c.onError(errorCode));
+ executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
} finally {
restoreCallingIdentity(callingIdentity);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
index 0bd3e5ed354e..0f627b92a24c 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -26,5 +26,5 @@ import android.telephony.ims.RcsContactUceCapability;
oneway interface IRcsUceControllerCallback {
void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
void onComplete();
- void onError(int errorCode);
+ void onError(int errorCode, long retryAfterMilliseconds);
}
diff --git a/tests/BootImageProfileTest/TEST_MAPPING b/tests/BootImageProfileTest/TEST_MAPPING
deleted file mode 100644
index 1b569f9455bf..000000000000
--- a/tests/BootImageProfileTest/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "presubmit": [
- {
- "name": "BootImageProfileTest"
- }
- ]
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index d476e73837f4..a20f96d17278 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.close
-import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -52,7 +51,6 @@ import org.junit.runners.Parameterized
* Test app closes by pressing back button
* To run this test: `atest FlickerTests:CloseAppBackButtonTest`
*/
-@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index e3789fea5cba..4bbb38c4d71a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.close
-import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -52,7 +51,6 @@ import org.junit.runners.Parameterized
* Test app closes by pressing home button.
* To run this test: `atest FlickerTests:CloseAppHomeButtonTest`
*/
-@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 52718bec9148..3d8deb5cfc8d 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -34,7 +34,6 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.cts.install.lib.Install;
import com.android.cts.install.lib.InstallUtils;
-import com.android.cts.install.lib.LocalIntentSender;
import com.android.cts.install.lib.TestApp;
import com.android.cts.install.lib.Uninstall;
import com.android.cts.rollback.lib.Rollback;
@@ -258,10 +257,6 @@ public class StagedRollbackTest {
.getPackageManager().getPackageInstaller();
pi.abandonSession(sessionId);
- // Remove the first intent sender result, so that the next staged install session does not
- // erroneously think that it has itself been abandoned.
- // TODO(b/136260017): Restructure LocalIntentSender to negate the need for this step.
- LocalIntentSender.getIntentSenderResult();
Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
}
diff --git a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java b/tests/net/common/java/android/net/OemNetworkPreferencesTest.java
index b77ed6ab5a29..c9161b6d6441 100644
--- a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java
+++ b/tests/net/common/java/android/net/OemNetworkPreferencesTest.java
@@ -22,11 +22,14 @@ import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import android.os.Build;
import android.util.SparseArray;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,6 +37,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
+@IgnoreUpTo(Build.VERSION_CODES.R)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class OemNetworkPreferencesTest {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 2758f6156c16..ba87dc50e246 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -18,6 +18,8 @@ package com.android.server;
import static android.Manifest.permission.CHANGE_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
+import static android.content.Intent.ACTION_USER_ADDED;
+import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
@@ -1056,7 +1058,9 @@ public class ConnectivityServiceTest {
public void setUids(Set<UidRange> uids) {
mNetworkCapabilities.setUids(uids);
- updateCapabilitiesInternal(null /* defaultNetwork */, true);
+ if (mAgentRegistered) {
+ mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true);
+ }
}
public void setVpnType(int vpnType) {
@@ -1082,11 +1086,15 @@ public class ConnectivityServiceTest {
throws Exception {
if (mAgentRegistered) throw new IllegalStateException("already registered");
setUids(uids);
- mConfig.isMetered = isAlwaysMetered;
+ if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
mInterface = VPN_IFNAME;
mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
mNetworkCapabilities);
mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
+ verify(mNetworkManagementService, times(1))
+ .addVpnUidRanges(eq(mMockVpn.getNetId()), eq(uids.toArray(new UidRange[0])));
+ verify(mNetworkManagementService, never())
+ .removeVpnUidRanges(eq(mMockVpn.getNetId()), any());
mAgentRegistered = true;
mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities());
mNetworkAgent = mMockNetworkAgent.getNetworkAgent();
@@ -1141,28 +1149,6 @@ public class ConnectivityServiceTest {
mMockNetworkAgent.sendLinkProperties(lp);
}
- private NetworkCapabilities updateCapabilitiesInternal(Network defaultNetwork,
- boolean sendToConnectivityService) {
- if (!mAgentRegistered) return null;
- super.updateCapabilities(defaultNetwork);
- // Because super.updateCapabilities will update the capabilities of the agent but
- // not the mock agent, the mock agent needs to know about them.
- copyCapabilitiesToNetworkAgent(sendToConnectivityService);
- return new NetworkCapabilities(mNetworkCapabilities);
- }
-
- private void copyCapabilitiesToNetworkAgent(boolean sendToConnectivityService) {
- if (null != mMockNetworkAgent) {
- mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities,
- sendToConnectivityService);
- }
- }
-
- @Override
- public NetworkCapabilities updateCapabilities(Network defaultNetwork) {
- return updateCapabilitiesInternal(defaultNetwork, false);
- }
-
public void disconnect() {
if (mMockNetworkAgent != null) mMockNetworkAgent.disconnect();
mAgentRegistered = false;
@@ -4944,8 +4930,6 @@ public class ConnectivityServiceTest {
final Network[] cellAndVpn = new Network[] {
mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
- Network[] cellAndWifi = new Network[] {
- mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()};
// A VPN with default (null) underlying networks sets the underlying network's interfaces...
expectForceUpdateIfaces(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
@@ -4955,10 +4939,13 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
+ final Network[] onlyNull = new Network[]{null};
final Network[] wifiAndVpn = new Network[] {
mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
- cellAndWifi = new Network[] {
+ final Network[] cellAndWifi = new Network[] {
mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()};
+ final Network[] cellNullAndWifi = new Network[] {
+ mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()};
waitForIdle();
assertEquals(wifiLp, mService.getActiveLinkProperties());
@@ -4984,6 +4971,13 @@ public class ConnectivityServiceTest {
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
reset(mStatsService);
+ // Null underlying networks are ignored.
+ mService.setUnderlyingNetworksForVpn(cellNullAndWifi);
+ waitForIdle();
+ expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
+ new String[]{MOBILE_IFNAME, WIFI_IFNAME});
+ reset(mStatsService);
+
// If an underlying network disconnects, that interface should no longer be underlying.
// This doesn't actually work because disconnectAndDestroyNetwork only notifies
// NetworkStatsService before the underlying network is actually removed. So the underlying
@@ -5018,6 +5012,7 @@ public class ConnectivityServiceTest {
argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.length == 1
&& WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces[0])));
mEthernetNetworkAgent.disconnect();
+ waitForIdle();
reset(mStatsService);
// When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo
@@ -5030,6 +5025,25 @@ public class ConnectivityServiceTest {
waitForIdle();
expectForceUpdateIfaces(wifiAndVpn, null);
reset(mStatsService);
+
+ // Specifying only a null underlying network is the same as no networks.
+ mService.setUnderlyingNetworksForVpn(onlyNull);
+ waitForIdle();
+ expectForceUpdateIfaces(wifiAndVpn, null);
+ reset(mStatsService);
+
+ // Specifying networks that are all disconnected is the same as specifying no networks.
+ mService.setUnderlyingNetworksForVpn(onlyCell);
+ waitForIdle();
+ expectForceUpdateIfaces(wifiAndVpn, null);
+ reset(mStatsService);
+
+ // Passing in null again means follow the default network again.
+ mService.setUnderlyingNetworksForVpn(null);
+ waitForIdle();
+ expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
+ new String[]{WIFI_IFNAME});
+ reset(mStatsService);
}
@Test
@@ -5471,6 +5485,7 @@ public class ConnectivityServiceTest {
final Set<UidRange> ranges = uidRangesForUid(uid);
mMockVpn.registerAgent(ranges);
+ mService.setUnderlyingNetworksForVpn(new Network[0]);
// VPN networks do not satisfy the default request and are automatically validated
// by NetworkMonitor
@@ -5479,19 +5494,12 @@ public class ConnectivityServiceTest {
mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */);
mMockVpn.connect(false);
- mService.setUnderlyingNetworksForVpn(new Network[0]);
- genericNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
+ genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback();
- vpnNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
- defaultCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
- assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
-
- genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
- genericNotVpnNetworkCallback.assertNoCallback();
- vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, nc -> null == nc.getUids());
- defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
+ vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
+ defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
ranges.clear();
@@ -5884,6 +5892,75 @@ public class ConnectivityServiceTest {
}
@Test
+ public void testVpnRestrictedUsers() throws Exception {
+ // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities.
+ mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
+ PERMISSION_GRANTED);
+
+ final NetworkRequest request = new NetworkRequest.Builder()
+ .removeCapability(NET_CAPABILITY_NOT_VPN)
+ .build();
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(request, callback);
+
+ // Bring up a VPN
+ mMockVpn.establishForMyUid();
+ callback.expectAvailableThenValidatedCallbacks(mMockVpn);
+ callback.assertNoCallback();
+
+ final int uid = Process.myUid();
+ NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
+ assertNotNull("nc=" + nc, nc.getUids());
+ assertEquals(nc.getUids(), uidRangesForUid(uid));
+
+ // Set an underlying network and expect to see the VPN transports change.
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(true);
+ callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ callback.expectCapabilitiesThat(mMockVpn, (caps)
+ -> caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_WIFI));
+ callback.expectCapabilitiesThat(mWiFiNetworkAgent, (caps)
+ -> caps.hasCapability(NET_CAPABILITY_VALIDATED));
+
+ // Create a fake restricted profile whose parent is our user ID.
+ final int userId = UserHandle.getUserId(uid);
+ final int restrictedUserId = userId + 1;
+ final UserInfo info = new UserInfo(restrictedUserId, "user", UserInfo.FLAG_RESTRICTED);
+ info.restrictedProfileParentId = userId;
+ assertTrue(info.isRestricted());
+ when(mUserManager.getUserInfo(restrictedUserId)).thenReturn(info);
+ final Intent addedIntent = new Intent(ACTION_USER_ADDED);
+ addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId);
+
+ // Send a USER_ADDED broadcast for it.
+ // The BroadcastReceiver for this broadcast checks that is being run on the handler thread.
+ final Handler handler = new Handler(mCsHandlerThread.getLooper());
+ handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
+
+ // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
+ // restricted user.
+ callback.expectCapabilitiesThat(mMockVpn, (caps)
+ -> caps.getUids().size() == 2
+ && caps.getUids().contains(new UidRange(uid, uid))
+ && caps.getUids().contains(UidRange.createForUser(restrictedUserId))
+ && caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_WIFI));
+
+ // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
+ final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
+ removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId);
+ handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
+
+ // Expect that the VPN gains the UID range for the restricted user.
+ callback.expectCapabilitiesThat(mMockVpn, (caps)
+ -> caps.getUids().size() == 1
+ && caps.getUids().contains(new UidRange(uid, uid))
+ && caps.hasTransport(TRANSPORT_VPN)
+ && caps.hasTransport(TRANSPORT_WIFI));
+ }
+
+ @Test
public void testIsActiveNetworkMeteredOverWifi() throws Exception {
// Returns true by default when no network is available.
assertTrue(mCm.isActiveNetworkMetered());
@@ -6829,8 +6906,8 @@ public class ConnectivityServiceTest {
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
mMockVpn.establish(lp, VPN_UID, vpnRange);
- // Connected VPN should have interface rules set up. There are two expected invocations,
- // one during VPN uid update, one during VPN LinkProperties update
+ // A connected VPN should have interface rules set up. There are two expected invocations,
+ // one during the VPN initial connection, one during the VPN LinkProperties update.
ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class);
verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture());
assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID);
@@ -7345,20 +7422,14 @@ public class ConnectivityServiceTest {
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
- // setUp() calls mockVpn() which adds a VPN with the Test Runner's uid. Configure it to be
- // active
- final VpnInfo info = new VpnInfo();
- info.ownerUid = Process.myUid();
- info.vpnIface = VPN_IFNAME;
- mMockVpn.setVpnInfo(info);
-
mMockVpn.establishForMyUid();
- waitForIdle();
+ // Wait for networks to connect and broadcasts to be sent before removing permissions.
+ waitForIdle();
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
-
assertTrue(mService.setUnderlyingNetworksForVpn(new Network[] {network}));
+ waitForIdle();
assertTrue(
"Active VPN permission not applied",
mService.checkConnectivityDiagnosticsPermissions(
@@ -7366,6 +7437,7 @@ public class ConnectivityServiceTest {
mContext.getOpPackageName()));
assertTrue(mService.setUnderlyingNetworksForVpn(null));
+ waitForIdle();
assertFalse(
"VPN shouldn't receive callback on non-underlying network",
mService.checkConnectivityDiagnosticsPermissions(
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 1dcc07c6db81..d0db55f2bb13 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -41,6 +41,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
@@ -86,10 +87,10 @@ import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.INetworkManagementService;
-import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.test.TestLooper;
import android.provider.Settings;
import android.security.Credentials;
import android.security.KeyStore;
@@ -100,6 +101,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
+import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
import com.android.server.IpSecService;
@@ -223,6 +225,8 @@ public class VpnTest {
.thenReturn(mNotificationManager);
when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
.thenReturn(mConnectivityManager);
+ when(mContext.getSystemServiceName(eq(ConnectivityManager.class)))
+ .thenReturn(Context.CONNECTIVITY_SERVICE);
when(mContext.getSystemService(eq(Context.IPSEC_SERVICE))).thenReturn(mIpSecManager);
when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
.thenReturn(Resources.getSystem().getString(
@@ -589,7 +593,7 @@ public class VpnTest {
}
@Test
- public void testNotificationShownForAlwaysOnApp() {
+ public void testNotificationShownForAlwaysOnApp() throws Exception {
final UserHandle userHandle = UserHandle.of(primaryUser.id);
final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser);
@@ -619,7 +623,6 @@ public class VpnTest {
@Test
public void testCapabilities() {
- final Vpn vpn = createVpn(primaryUser.id);
setMockedUsers(primaryUser);
final Network mobile = new Network(1);
@@ -1037,7 +1040,7 @@ public class VpnTest {
when(exception.getErrorType())
.thenReturn(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED);
- final Vpn vpn = startLegacyVpn(mVpnProfile);
+ final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), (mVpnProfile));
final NetworkCallback cb = triggerOnAvailableAndGetCallback();
// Wait for createIkeSession() to be called before proceeding in order to ensure consistent
@@ -1048,20 +1051,20 @@ public class VpnTest {
ikeCb.onClosedExceptionally(exception);
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
- assertEquals(DetailedState.FAILED, vpn.getNetworkInfo().getDetailedState());
+ assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state);
}
@Test
public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception {
when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any()))
.thenThrow(new IllegalArgumentException());
- final Vpn vpn = startLegacyVpn(mVpnProfile);
+ final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
final NetworkCallback cb = triggerOnAvailableAndGetCallback();
// Wait for createIkeSession() to be called before proceeding in order to ensure consistent
// state
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
- assertEquals(DetailedState.FAILED, vpn.getNetworkInfo().getDetailedState());
+ assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state);
}
private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) {
@@ -1100,8 +1103,7 @@ public class VpnTest {
// a subsequent CL.
}
- public Vpn startLegacyVpn(final VpnProfile vpnProfile) throws Exception {
- final Vpn vpn = createVpn(primaryUser.id);
+ private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception {
setMockedUsers(primaryUser);
// Dummy egress interface
@@ -1118,7 +1120,7 @@ public class VpnTest {
@Test
public void testStartPlatformVpn() throws Exception {
- startLegacyVpn(mVpnProfile);
+ startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
// TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in
// a subsequent patch.
}
@@ -1153,7 +1155,7 @@ public class VpnTest {
legacyRunnerReady.open();
return new Network(102);
});
- final Vpn vpn = startLegacyVpn(profile);
+ final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile);
final TestDeps deps = (TestDeps) vpn.mDeps;
try {
// udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK
@@ -1287,8 +1289,13 @@ public class VpnTest {
doReturn(UserHandle.of(userId)).when(asUserContext).getUser();
when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt()))
.thenReturn(asUserContext);
- return new Vpn(Looper.myLooper(), mContext, new TestDeps(), mNetService,
+ final TestLooper testLooper = new TestLooper();
+ final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService,
userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
+ verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat(
+ provider -> provider.getName().contains("VpnNetworkProvider")
+ ));
+ return vpn;
}
private static void assertBlocked(Vpn vpn, int... uids) {