summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java10
-rw-r--r--apct-tests/perftests/core/Android.bp3
-rw-r--r--apct-tests/perftests/core/AndroidTest.xml27
-rw-r--r--apct-tests/perftests/multiuser/Android.bp1
-rw-r--r--apct-tests/perftests/multiuser/AndroidManifest.xml3
-rw-r--r--apct-tests/perftests/multiuser/AndroidTest.xml34
-rw-r--r--apct-tests/perftests/windowmanager/Android.bp1
-rw-r--r--apex/jobscheduler/framework/java/android/app/AlarmManager.java8
-rw-r--r--apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java230
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java13
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobStore.java19
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java10
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java23
-rw-r--r--apex/statsd/aidl/android/os/IStatsCompanionService.aidl11
-rw-r--r--apex/statsd/aidl/android/os/IStatsd.aidl7
-rw-r--r--apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java66
-rw-r--r--api/current.txt2
-rw-r--r--api/module-lib-current.txt8
-rwxr-xr-xapi/system-current.txt8
-rw-r--r--cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl1
-rw-r--r--cmds/idmap2/libidmap2/ResourceMapping.cpp7
-rw-r--r--cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h4
-rw-r--r--cmds/idmap2/tests/R.h36
-rw-r--r--cmds/idmap2/tests/ResourceMappingTests.cpp18
-rw-r--r--cmds/idmap2/tests/TestConstants.h8
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-no-name-static.apkbin3477 -> 3485 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-no-name.apkbin3389 -> 3393 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-shared.apkbin3757 -> 3757 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-static-1.apkbin3469 -> 3477 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay-static-2.apkbin3469 -> 3477 bytes
-rw-r--r--cmds/idmap2/tests/data/overlay/overlay.apkbin3489 -> 3489 bytes
-rw-r--r--cmds/idmap2/tests/data/signature-overlay/signature-overlay.apkbin1315 -> 1299 bytes
-rw-r--r--cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml1
-rw-r--r--cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apkbin1827 -> 1907 bytes
-rw-r--r--cmds/idmap2/tests/data/system-overlay/system-overlay.apkbin1319 -> 1387 bytes
-rw-r--r--cmds/idmap2/tests/data/target/res/values/overlayable.xml4
-rw-r--r--cmds/idmap2/tests/data/target/res/values/values.xml1
-rw-r--r--cmds/idmap2/tests/data/target/target-no-overlayable.apkbin2311 -> 2391 bytes
-rw-r--r--cmds/idmap2/tests/data/target/target.apkbin5097 -> 5201 bytes
-rw-r--r--cmds/screencap/screencap.cpp31
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp76
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h30
-rw-r--r--cmds/statsd/src/StatsService.cpp32
-rw-r--r--cmds/statsd/src/StatsService.h5
-rw-r--r--cmds/statsd/src/atoms.proto2
-rw-r--r--cmds/statsd/src/config/ConfigManager.cpp2
-rw-r--r--cmds/statsd/src/config/ConfigManager.h2
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp4
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h2
-rw-r--r--cmds/statsd/src/packages/PackageInfoListener.h2
-rw-r--r--cmds/statsd/src/packages/UidMap.h1
-rw-r--r--cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp264
-rw-r--r--cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java6
-rw-r--r--cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java10
-rw-r--r--core/java/android/animation/AnimatorSet.java20
-rw-r--r--core/java/android/app/Activity.java2
-rw-r--r--core/java/android/app/ActivityManagerInternal.java2
-rw-r--r--core/java/android/app/Dialog.java15
-rw-r--r--core/java/android/app/WallpaperManager.java5
-rw-r--r--core/java/android/app/WindowContext.java2
-rw-r--r--core/java/android/app/backup/BackupAgent.java2
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java2
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java12
-rw-r--r--core/java/android/companion/BluetoothDeviceFilter.java10
-rw-r--r--core/java/android/content/ContentProvider.java5
-rw-r--r--core/java/android/content/ContentResolver.java2
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/SyncStatusInfo.java2
-rw-r--r--core/java/android/content/pm/PackageParser.java6
-rw-r--r--core/java/android/content/pm/dex/DexMetadataHelper.java4
-rw-r--r--core/java/android/content/res/Configuration.java2
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java2
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java2
-rw-r--r--core/java/android/os/DropBoxManager.java2
-rw-r--r--core/java/android/os/FileUtils.java2
-rw-r--r--core/java/android/os/GraphicsEnvironment.java2
-rw-r--r--core/java/android/os/OWNERS2
-rw-r--r--core/java/android/os/TEST_MAPPING10
-rw-r--r--core/java/android/os/ZygoteProcess.java42
-rw-r--r--core/java/android/provider/Settings.java35
-rw-r--r--core/java/android/service/notification/NotificationStats.java5
-rw-r--r--core/java/android/telephony/TelephonyRegistryManager.java29
-rw-r--r--core/java/android/util/proto/ProtoInputStream.java6
-rw-r--r--core/java/android/util/proto/ProtoOutputStream.java8
-rw-r--r--core/java/android/view/FocusFinder.java19
-rw-r--r--core/java/android/view/GestureDetector.java10
-rw-r--r--core/java/android/view/LayoutInflater.java4
-rw-r--r--core/java/android/view/Surface.java6
-rw-r--r--core/java/android/view/SurfaceControl.java351
-rw-r--r--core/java/android/view/View.java8
-rw-r--r--core/java/android/view/ViewConfiguration.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java36
-rw-r--r--core/java/android/view/Window.java5
-rw-r--r--core/java/android/view/WindowManager.java1
-rw-r--r--core/java/android/view/WindowManagerImpl.java2
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java4
-rw-r--r--core/java/android/view/inputmethod/InlineSuggestionsRequest.java20
-rw-r--r--core/java/android/view/inputmethod/InlineSuggestionsResponse.java38
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java3
-rw-r--r--core/java/android/widget/AbsListView.java3
-rw-r--r--core/java/android/widget/Gallery.java3
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java4
-rwxr-xr-xcore/java/android/widget/SearchView.java2
-rw-r--r--core/java/android/widget/TEST_MAPPING39
-rw-r--r--core/java/android/widget/inline/InlineContentView.java2
-rw-r--r--core/java/android/widget/inline/TEST_MAPPING15
-rw-r--r--core/java/com/android/internal/app/LocalePicker.java64
-rw-r--r--core/java/com/android/internal/infra/AbstractRemoteService.java2
-rw-r--r--core/java/com/android/internal/os/ChildZygoteInit.java2
-rw-r--r--core/java/com/android/internal/os/OWNERS2
-rw-r--r--core/java/com/android/internal/os/Zygote.java4
-rw-r--r--core/java/com/android/internal/os/ZygoteArguments.java10
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java12
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java5
-rw-r--r--core/java/com/android/internal/os/ZygoteServer.java2
-rw-r--r--core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java7
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java5
-rw-r--r--core/java/com/android/internal/telephony/ITelephonyRegistry.aidl6
-rw-r--r--core/java/com/android/server/SystemConfig.java36
-rw-r--r--core/jni/OWNERS2
-rw-r--r--core/jni/android_hardware_input_InputApplicationHandle.cpp23
-rw-r--r--core/jni/android_hardware_input_InputApplicationHandle.h3
-rw-r--r--core/jni/android_hardware_input_InputWindowHandle.cpp4
-rw-r--r--core/jni/android_media_AudioSystem.cpp2
-rw-r--r--core/jni/android_net_NetUtils.cpp6
-rw-r--r--core/jni/android_os_Debug.cpp2
-rw-r--r--core/jni/android_os_Parcel.cpp2
-rw-r--r--core/jni/android_util_Binder.cpp2
-rw-r--r--core/jni/android_view_InputQueue.cpp4
-rw-r--r--core/jni/android_view_SurfaceControl.cpp179
-rw-r--r--core/proto/android/providers/settings/global.proto2
-rw-r--r--core/proto/android/server/alarm/alarmmanagerservice.proto5
-rw-r--r--core/proto/android/server/appstatetracker.proto14
-rw-r--r--core/res/res/drawable-car/car_dialog_button_background.xml15
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/sysprop/Android.bp21
-rw-r--r--core/sysprop/LocalizationProperties.sysprop24
-rw-r--r--core/sysprop/api/com.android.sysprop.localization-current.txt9
-rw-r--r--core/sysprop/api/com.android.sysprop.localization-latest.txt9
-rw-r--r--core/tests/bugreports/Android.bp6
-rw-r--r--core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java128
-rw-r--r--core/tests/coretests/apks/install/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_bad_dex/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_decl_perm/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_loc_auto/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_loc_internal/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_uses_feature/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/install_verifier_good/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/keyset/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/version/res/values/strings.xml4
-rw-r--r--core/tests/coretests/apks/version_nosys/res/values/strings.xml4
-rw-r--r--core/tests/coretests/src/android/os/VintfObjectTest.java2
-rw-r--r--data/keyboards/Generic.kl1
-rw-r--r--data/keyboards/Vendor_2dc8_Product_6101.kl55
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java30
-rw-r--r--libs/androidfw/Android.bp2
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h4
-rw-r--r--libs/androidfw/libandroidfw_blocklist.txt (renamed from libs/androidfw/libandroidfw_blacklist.txt)0
-rw-r--r--libs/hwui/ColorMode.h34
-rw-r--r--libs/hwui/apex/jni_runtime.cpp15
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp13
-rw-r--r--libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp2
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.cpp26
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.h4
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp11
-rw-r--r--libs/hwui/renderthread/CanvasContext.h4
-rw-r--r--libs/hwui/renderthread/EglManager.cpp105
-rw-r--r--libs/hwui/renderthread/EglManager.h4
-rw-r--r--libs/hwui/renderthread/IRenderPipeline.h11
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp4
-rw-r--r--libs/hwui/renderthread/RenderProxy.h3
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp9
-rw-r--r--libs/hwui/utils/Color.cpp22
-rw-r--r--libs/hwui/utils/Color.h1
-rw-r--r--location/java/android/location/GnssAntennaInfo.java107
-rwxr-xr-xmedia/java/android/media/AudioManager.java88
-rw-r--r--media/java/android/media/AudioRecord.java5
-rw-r--r--media/java/android/media/ExifInterface.java6
-rw-r--r--media/java/android/media/ImageReader.java12
-rw-r--r--media/java/android/media/audiopolicy/AudioPolicy.java11
-rw-r--r--media/java/android/media/audiopolicy/AudioPolicyConfig.java6
-rw-r--r--media/jni/android_media_ImageReader.cpp21
-rw-r--r--media/jni/android_media_MediaPlayer.cpp2
-rw-r--r--media/jni/android_media_MediaSync.cpp2
-rw-r--r--media/jni/android_media_tv_Tuner.cpp5
-rw-r--r--media/jni/android_media_tv_Tuner.h5
-rw-r--r--media/jni/audioeffect/Visualizer.cpp33
-rw-r--r--media/jni/audioeffect/Visualizer.h34
-rw-r--r--media/jni/audioeffect/android_media_AudioEffect.cpp21
-rw-r--r--media/jni/audioeffect/android_media_Visualizer.cpp10
-rw-r--r--media/mca/filterfw/java/android/filterfw/core/FilterFunction.java2
-rw-r--r--media/mca/filterfw/jni/jni_native_program.cpp2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java24
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/Preconditions.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java48
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2CaptureRequestTest.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2StillCaptureTest.java2
-rw-r--r--non-updatable-api/current.txt2
-rw-r--r--non-updatable-api/module-lib-current.txt8
-rw-r--r--non-updatable-api/system-current.txt8
-rw-r--r--packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java10
-rw-r--r--packages/CarSystemUI/res/values/config.xml25
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java19
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java125
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java12
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java28
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java380
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java7
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java38
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java3
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java2
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java162
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java2
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java27
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java4
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java21
-rw-r--r--packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java2
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml4
-rw-r--r--packages/SettingsLib/res/values/strings.xml3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java22
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java4
-rw-r--r--packages/SimAppDialog/Android.bp1
-rw-r--r--packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.pngbin0 -> 1766 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/one_handed_tutorial.pngbin0 -> 1054 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/one_handed_tutorial.pngbin0 -> 2215 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/one_handed_tutorial.pngbin0 -> 3649 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxxhdpi/one_handed_tutorial.pngbin0 -> 5029 bytes
-rw-r--r--packages/SystemUI/res/values-af/strings.xml7
-rw-r--r--packages/SystemUI/res/values-am/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml7
-rw-r--r--packages/SystemUI/res/values-as/strings.xml7
-rw-r--r--packages/SystemUI/res/values-az/strings.xml7
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml7
-rw-r--r--packages/SystemUI/res/values-be/strings.xml9
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml7
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml7
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml7
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml7
-rw-r--r--packages/SystemUI/res/values-da/strings.xml7
-rw-r--r--packages/SystemUI/res/values-de/strings.xml7
-rw-r--r--packages/SystemUI/res/values-el/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml7
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml7
-rw-r--r--packages/SystemUI/res/values-es/strings.xml7
-rw-r--r--packages/SystemUI/res/values-et/strings.xml7
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml7
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml7
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml7
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml7
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml13
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml7
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml7
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml7
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml7
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml9
-rw-r--r--packages/SystemUI/res/values-in/strings.xml7
-rw-r--r--packages/SystemUI/res/values-is/strings.xml7
-rw-r--r--packages/SystemUI/res/values-it/strings.xml7
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml7
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml7
-rw-r--r--packages/SystemUI/res/values-km/strings.xml7
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml7
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml7
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml7
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml29
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml7
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml7
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml7
-rw-r--r--packages/SystemUI/res/values-my/strings.xml7
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml7
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml31
-rw-r--r--packages/SystemUI/res/values-or/strings.xml7
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml7
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml7
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml9
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml7
-rw-r--r--packages/SystemUI/res/values-si/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml7
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml7
-rw-r--r--packages/SystemUI/res/values-te/strings.xml7
-rw-r--r--packages/SystemUI/res/values-th/strings.xml7
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml7
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml7
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml7
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml7
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml7
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml7
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml7
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml7
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml7
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml7
-rw-r--r--packages/SystemUI/res/values/config.xml6
-rw-r--r--packages/SystemUI/res/values/strings.xml5
-rw-r--r--packages/SystemUI/res/xml/one_handed_tutorial.xml67
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java116
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java119
-rw-r--r--packages/SystemUI/src/com/android/systemui/BatteryMeterView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/DisplayIdIndexSupplier.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java161
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/dagger/PipMenuActivityClass.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java528
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java516
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java106
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt204
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java81
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt)22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt240
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt72
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java71
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java162
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java86
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java80
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java6
-rw-r--r--packages/Tethering/Android.bp1
-rw-r--r--packages/Tethering/AndroidManifest.xml2
-rw-r--r--packages/Tethering/proguard.flags2
-rw-r--r--packages/Tethering/src/android/net/ip/IpServer.java16
-rw-r--r--packages/Tethering/src/android/net/util/TetheringMessageBase.java2
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java6
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/Tethering.java80
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java2
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java28
-rw-r--r--services/Android.bp2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java123
-rw-r--r--services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java2
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetService.java12
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java3
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteFillService.java3
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java8
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java10
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java2
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java46
-rw-r--r--services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java2
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java39
-rw-r--r--services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java10
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java5
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java1
-rw-r--r--services/core/java/com/android/server/BinderCallsStatsService.java24
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java5
-rw-r--r--services/core/java/com/android/server/BluetoothService.java12
-rw-r--r--services/core/java/com/android/server/GestureLauncherService.java43
-rw-r--r--services/core/java/com/android/server/PinnerService.java16
-rw-r--r--services/core/java/com/android/server/ServiceWatcher.java54
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java18
-rw-r--r--services/core/java/com/android/server/SystemService.java107
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java177
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java19
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java31
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java16
-rw-r--r--services/core/java/com/android/server/am/CoreSettingsObserver.java2
-rw-r--r--services/core/java/com/android/server/appbinding/AppBindingService.java13
-rw-r--r--services/core/java/com/android/server/attention/AttentionManagerService.java12
-rwxr-xr-xservices/core/java/com/android/server/audio/AudioService.java37
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java14
-rw-r--r--services/core/java/com/android/server/camera/CameraServiceProxy.java11
-rw-r--r--services/core/java/com/android/server/clipboard/ClipboardService.java6
-rw-r--r--services/core/java/com/android/server/connectivity/PermissionMonitor.java33
-rw-r--r--services/core/java/com/android/server/content/ContentService.java19
-rw-r--r--services/core/java/com/android/server/display/ColorFade.java25
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java4
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayService.java49
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayShellCommand.java119
-rw-r--r--services/core/java/com/android/server/hdmi/ActiveSourceAction.java10
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java4
-rw-r--r--services/core/java/com/android/server/infra/AbstractMasterSystemService.java9
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java10
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java16
-rw-r--r--services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java3
-rw-r--r--services/core/java/com/android/server/location/LocationProviderProxy.java27
-rw-r--r--services/core/java/com/android/server/location/geofence/GeofenceProxy.java2
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java13
-rw-r--r--services/core/java/com/android/server/media/MediaButtonReceiverHolder.java4
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java15
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java7
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java12
-rw-r--r--services/core/java/com/android/server/om/IdmapManager.java34
-rw-r--r--services/core/java/com/android/server/om/OverlayActorEnforcer.java20
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java19
-rw-r--r--services/core/java/com/android/server/om/OverlayReferenceMapper.java16
-rw-r--r--services/core/java/com/android/server/om/OverlayableInfoCallback.java83
-rw-r--r--services/core/java/com/android/server/om/PackageManagerHelper.java66
-rw-r--r--services/core/java/com/android/server/os/TEST_MAPPING10
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java20
-rw-r--r--services/core/java/com/android/server/pm/BackgroundDexOptService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java8
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java260
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java564
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageVerificationState.java8
-rw-r--r--services/core/java/com/android/server/pm/Settings.java12
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java9
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java1
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java13
-rw-r--r--services/core/java/com/android/server/pm/dex/OWNERS2
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java94
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyService.java13
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java25
-rw-r--r--services/core/java/com/android/server/role/RoleManagerService.java8
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerService.java6
-rw-r--r--services/core/java/com/android/server/search/SearchManagerService.java22
-rw-r--r--services/core/java/com/android/server/slice/SliceManagerService.java11
-rw-r--r--services/core/java/com/android/server/storage/StorageUserConnection.java48
-rw-r--r--services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java13
-rw-r--r--services/core/java/com/android/server/textservices/TextServicesManagerService.java13
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java23
-rwxr-xr-xservices/core/java/com/android/server/tv/TvInputManagerService.java8
-rw-r--r--services/core/java/com/android/server/vr/VrManagerService.java10
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java93
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java23
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java41
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java21
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java8
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java19
-rw-r--r--services/core/java/com/android/server/wm/Task.java126
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java13
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java25
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java77
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp20
-rw-r--r--services/core/jni/stats/PowerStatsPuller.cpp15
-rw-r--r--services/core/jni/stats/SubsystemSleepStatePuller.cpp56
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java13
-rw-r--r--services/java/com/android/server/SystemServer.java7
-rw-r--r--services/midi/java/com/android/server/midi/MidiService.java7
-rw-r--r--services/print/java/com/android/server/print/PrintManagerService.java9
-rw-r--r--services/profcollect/Android.bp35
-rw-r--r--services/profcollect/OWNERS3
-rw-r--r--services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java196
-rw-r--r--services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java7
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java106
-rw-r--r--services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java100
-rw-r--r--services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java81
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/job/JobSetTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt10
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java88
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java53
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt6
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java39
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java27
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java82
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java111
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java22
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java108
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java607
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java74
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java84
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java60
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java93
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java29
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java82
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerMapTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java574
-rw-r--r--services/usage/java/com/android/server/usage/AppTimeLimitController.java4
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java17
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java46
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java4
-rwxr-xr-xtelecomm/java/android/telecom/Call.java6
-rwxr-xr-xtelecomm/java/android/telecom/Connection.java2
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java1
-rwxr-xr-xtelecomm/java/android/telecom/InCallAdapter.java4
-rw-r--r--telephony/api/system-current.txt1
-rw-r--r--telephony/common/android/telephony/LocationAccessPolicy.java6
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java14
-rw-r--r--telephony/common/com/google/android/mms/pdu/PduComposer.java2
-rwxr-xr-xtelephony/common/com/google/android/mms/pdu/PduPersister.java10
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthNr.java2
-rw-r--r--telephony/java/android/telephony/MbmsDownloadSession.java2
-rw-r--r--telephony/java/android/telephony/PreciseDataConnectionState.java159
-rw-r--r--telephony/java/android/telephony/SmsManager.java5
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java7
-rw-r--r--telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java6
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java22
-rwxr-xr-xtelephony/java/android/telephony/ims/ImsCallSession.java2
-rw-r--r--telephony/java/android/telephony/ims/ImsReasonInfo.java197
-rw-r--r--telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java12
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java4
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java4
-rw-r--r--telephony/java/android/telephony/mbms/MbmsTempFileProvider.java2
-rw-r--r--telephony/java/com/android/ims/internal/IImsCallSession.aidl4
-rw-r--r--telephony/java/com/android/ims/internal/IImsConfig.aidl8
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java4
-rw-r--r--tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java (renamed from tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java)8
-rw-r--r--tests/BootImageProfileTest/OWNERS4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt30
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt10
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt15
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt5
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt15
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt121
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt20
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt39
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt49
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt30
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt12
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt21
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt9
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt31
-rw-r--r--tests/LocalizationTest/Android.bp41
-rw-r--r--tests/LocalizationTest/AndroidManifest.xml (renamed from core/res/res/drawable-car-night/car_dialog_button_background.xml)29
-rw-r--r--tests/LocalizationTest/AndroidTest.xml34
-rw-r--r--tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.kt118
-rw-r--r--tests/net/common/java/android/net/NetworkProviderTest.kt14
-rw-r--r--tests/net/java/com/android/server/NetIdManagerTest.kt2
-rw-r--r--tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java124
-rw-r--r--tests/utils/StubIME/Android.bp (renamed from tests/utils/DummyIME/Android.bp)2
-rw-r--r--tests/utils/StubIME/AndroidManifest.xml (renamed from tests/utils/DummyIME/AndroidManifest.xml)12
-rw-r--r--tests/utils/StubIME/res/xml/method.xml (renamed from tests/utils/DummyIME/res/xml/method.xml)4
-rw-r--r--tests/utils/StubIME/src/com/android/testing/stubime/ImePreferences.java (renamed from tests/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java)4
-rw-r--r--tests/utils/StubIME/src/com/android/testing/stubime/StubIme.java (renamed from tests/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java)6
-rw-r--r--tools/aapt2/ResourceParser.cpp2
-rw-r--r--tools/aapt2/ResourceUtils.cpp2
-rw-r--r--tools/aapt2/Resources.proto1
-rw-r--r--tools/aapt2/cmd/Link.cpp6
-rw-r--r--tools/aapt2/cmd/Optimize.cpp6
-rw-r--r--tools/aapt2/cmd/Optimize.h4
-rw-r--r--tools/aapt2/compile/PngChunkFilter.cpp6
-rw-r--r--tools/aapt2/configuration/ConfigurationParser_test.cpp2
-rw-r--r--tools/aapt2/dump/DumpManifest.cpp22
-rw-r--r--tools/aapt2/format/binary/TableFlattener_test.cpp4
-rw-r--r--tools/aapt2/format/proto/ProtoDeserialize.cpp3
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize.cpp3
-rw-r--r--tools/aapt2/jni/aapt2_jni.cpp2
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp4
-rw-r--r--tools/aapt2/link/TableMerger.cpp20
-rw-r--r--tools/aapt2/link/TableMerger.h4
-rw-r--r--tools/aapt2/link/XmlCompatVersioner.cpp4
-rw-r--r--tools/aapt2/optimize/ResourceFilter.cpp6
-rw-r--r--tools/aapt2/optimize/ResourceFilter.h6
-rw-r--r--tools/aapt2/optimize/ResourceFilter_test.cpp46
-rw-r--r--tools/aapt2/test/Common.cpp4
-rw-r--r--tools/aapt2/trace/TraceBuffer.h2
-rw-r--r--tools/aapt2/util/Maybe_test.cpp34
-rw-r--r--tools/aapt2/xml/XmlActionExecutor.cpp8
-rw-r--r--tools/aapt2/xml/XmlActionExecutor.h4
-rw-r--r--tools/aapt2/xml/XmlActionExecutor_test.cpp4
-rwxr-xr-xtools/aosp/aosp_sha.sh2
-rwxr-xr-xtools/hiddenapi/generate_hiddenapi_lists.py127
-rwxr-xr-xtools/hiddenapi/generate_hiddenapi_lists_test.py39
-rw-r--r--tools/stats_log_api_gen/Collation.cpp14
-rw-r--r--tools/stats_log_api_gen/Collation.h10
-rw-r--r--tools/stats_log_api_gen/java_writer.cpp28
-rw-r--r--tools/stats_log_api_gen/java_writer.h7
-rw-r--r--tools/stats_log_api_gen/java_writer_q.cpp4
-rw-r--r--tools/stats_log_api_gen/java_writer_q.h7
-rw-r--r--tools/stats_log_api_gen/main.cpp23
-rw-r--r--tools/stats_log_api_gen/native_writer.cpp16
-rw-r--r--tools/stats_log_api_gen/native_writer.h7
-rw-r--r--tools/stats_log_api_gen/test_collation.cpp7
-rw-r--r--tools/stats_log_api_gen/utils.cpp49
-rw-r--r--tools/stats_log_api_gen/utils.h20
-rw-r--r--wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java30
-rw-r--r--wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java24
-rw-r--r--wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java2
721 files changed, 11294 insertions, 6511 deletions
diff --git a/Android.bp b/Android.bp
index 4cb9020f878f..0780f88df7c6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -467,6 +467,7 @@ java_library {
"com.android.sysprop.apex",
"com.android.sysprop.init",
+ "com.android.sysprop.localization",
"PlatformProperties",
],
sdk_version: "core_platform",
diff --git a/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java b/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java
index 23f025b0a759..5a04ba303b66 100644
--- a/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java
+++ b/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java
@@ -27,7 +27,7 @@ import android.support.test.uiautomator.UiDevice;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.utils.blob.DummyBlobData;
+import com.android.utils.blob.FakeBlobData;
import org.junit.After;
import org.junit.Before;
@@ -96,7 +96,7 @@ public class BlobStorePerfTests {
mAtraceUtils.startTrace(ATRACE_CATEGORY_SYSTEM_SERVER);
try {
final List<Long> durations = new ArrayList<>();
- final DummyBlobData blobData = prepareDataBlob(fileSizeInMb);
+ final FakeBlobData blobData = prepareDataBlob(fileSizeInMb);
final TraceMarkParser parser = new TraceMarkParser(
line -> line.name.startsWith(ATRACE_COMPUTE_DIGEST_PREFIX));
while (mState.keepRunning(durations)) {
@@ -120,15 +120,15 @@ public class BlobStorePerfTests {
});
}
- private DummyBlobData prepareDataBlob(int fileSizeInMb) throws Exception {
- final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+ private FakeBlobData prepareDataBlob(int fileSizeInMb) throws Exception {
+ final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
.setFileSize(fileSizeInMb * 1024 * 1024 /* bytes */)
.build();
blobData.prepare();
return blobData;
}
- private void commitBlob(DummyBlobData blobData) throws Exception {
+ private void commitBlob(FakeBlobData blobData) throws Exception {
final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
blobData.writeToSession(session);
diff --git a/apct-tests/perftests/core/Android.bp b/apct-tests/perftests/core/Android.bp
index 03ab5b6f2c8c..92dbc263cb34 100644
--- a/apct-tests/perftests/core/Android.bp
+++ b/apct-tests/perftests/core/Android.bp
@@ -17,11 +17,14 @@ android_test {
"apct-perftests-overlay-apps",
"apct-perftests-resources-manager-apps",
"apct-perftests-utils",
+ "collector-device-lib",
"guava",
],
libs: ["android.test.base"],
+ data: [":perfetto_artifacts"],
+
platform_apis: true,
jni_libs: ["libperftestscore_jni"],
diff --git a/apct-tests/perftests/core/AndroidTest.xml b/apct-tests/perftests/core/AndroidTest.xml
index 1b289130124f..4f8ee2927d51 100644
--- a/apct-tests/perftests/core/AndroidTest.xml
+++ b/apct-tests/perftests/core/AndroidTest.xml
@@ -16,13 +16,40 @@
<configuration description="Runs CorePerfTests metric instrumentation.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-metric-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+ </target_preparer>
+
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CorePerfTests.apk" />
</target_preparer>
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path" />
+ </metrics_collector>
+
+ <!-- Needed for storing the perfetto files in external storage-->
+ <option name="isolated-storage" value="false" />
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.perftests.core" />
<option name="hidden-api-checks" value="false"/>
+
+ <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
+ <!-- ProcLoadListener related arguments -->
+ <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
+ <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+ <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+ <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
+
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+ <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
</test>
</configuration>
diff --git a/apct-tests/perftests/multiuser/Android.bp b/apct-tests/perftests/multiuser/Android.bp
index 04432f25e337..fc45d4adcc15 100644
--- a/apct-tests/perftests/multiuser/Android.bp
+++ b/apct-tests/perftests/multiuser/Android.bp
@@ -22,5 +22,6 @@ android_test {
],
platform_apis: true,
test_suites: ["device-tests"],
+ data: [":perfetto_artifacts"],
certificate: "platform",
}
diff --git a/apct-tests/perftests/multiuser/AndroidManifest.xml b/apct-tests/perftests/multiuser/AndroidManifest.xml
index e4196dd6cf12..cb05651a3eec 100644
--- a/apct-tests/perftests/multiuser/AndroidManifest.xml
+++ b/apct-tests/perftests/multiuser/AndroidManifest.xml
@@ -17,7 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.perftests.multiuser">
- <uses-sdk android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
@@ -25,8 +24,6 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.REAL_GET_TASKS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/apct-tests/perftests/multiuser/AndroidTest.xml b/apct-tests/perftests/multiuser/AndroidTest.xml
index 9117561fe1e5..c7929af6077f 100644
--- a/apct-tests/perftests/multiuser/AndroidTest.xml
+++ b/apct-tests/perftests/multiuser/AndroidTest.xml
@@ -16,14 +16,48 @@
<configuration description="Runs MultiUserPerfTests metric instrumentation.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-metric-instrumentation" />
+
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="MultiUserPerfTests.apk" />
<option name="test-file-name" value="MultiUserPerfDummyApp.apk" />
</target_preparer>
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+ </target_preparer>
+
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path" />
+ </metrics_collector>
+
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false" />
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.perftests.multiuser" />
<option name="hidden-api-checks" value="false"/>
+
+ <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
+ <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
+ <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+ <!-- ProcLoadListener related arguments -->
+ <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
+ <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+ <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+ <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
+
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+ <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
</test>
</configuration>
diff --git a/apct-tests/perftests/windowmanager/Android.bp b/apct-tests/perftests/windowmanager/Android.bp
index 9e95a104af81..9fa99853ace3 100644
--- a/apct-tests/perftests/windowmanager/Android.bp
+++ b/apct-tests/perftests/windowmanager/Android.bp
@@ -19,6 +19,7 @@ android_test {
"androidx.test.rules",
"androidx.annotation_annotation",
"apct-perftests-utils",
+ "collector-device-lib",
"platform-test-annotations",
],
test_suites: ["device-tests"],
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 12ec9eb4eb73..7851087bac19 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -803,8 +803,8 @@ public class AlarmManager {
* <b>only</b> be used for situations where it is actually required that the alarm go off while
* in idle -- a reasonable example would be for a calendar notification that should make a
* sound so the user is aware of it. When the alarm is dispatched, the app will also be
- * added to the system's temporary whitelist for approximately 10 seconds to allow that
- * application to acquire further wake locks in which to complete its work.</p>
+ * added to the system's temporary power exemption list for approximately 10 seconds to allow
+ * that application to acquire further wake locks in which to complete its work.</p>
*
* <p>These alarms can significantly impact the power use
* of the device when idle (and thus cause significant battery blame to the app scheduling
@@ -855,8 +855,8 @@ public class AlarmManager {
* be used for situations where it is actually required that the alarm go off while in
* idle -- a reasonable example would be for a calendar notification that should make a
* sound so the user is aware of it. When the alarm is dispatched, the app will also be
- * added to the system's temporary whitelist for approximately 10 seconds to allow that
- * application to acquire further wake locks in which to complete its work.</p>
+ * added to the system's temporary power exemption list for approximately 10 seconds to allow
+ * that application to acquire further wake locks in which to complete its work.</p>
*
* <p>These alarms can significantly impact the power use
* of the device when idle (and thus cause significant battery blame to the app scheduling
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index 6d2363549604..876d73a570af 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -67,8 +67,8 @@ import java.util.Objects;
* Class to keep track of the information related to "force app standby", which includes:
* - OP_RUN_ANY_IN_BACKGROUND for each package
* - UID foreground/active state
- * - User+system power save whitelist
- * - Temporary power save whitelist
+ * - User+system power save exemption list
+ * - Temporary power save exemption list
* - Global "force all apps standby" mode enforced by battery saver.
*
* Test: atest com.android.server.AppStateTrackerTest
@@ -110,25 +110,25 @@ public class AppStateTrackerImpl implements AppStateTracker {
final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
/**
- * System except-idle + user whitelist in the device idle controller.
+ * System except-idle + user exemption list in the device idle controller.
*/
@GuardedBy("mLock")
- private int[] mPowerWhitelistedAllAppIds = new int[0];
+ private int[] mPowerExemptAllAppIds = new int[0];
/**
- * User whitelisted apps in the device idle controller.
+ * User exempted apps in the device idle controller.
*/
@GuardedBy("mLock")
- private int[] mPowerWhitelistedUserAppIds = new int[0];
+ private int[] mPowerExemptUserAppIds = new int[0];
@GuardedBy("mLock")
- private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
+ private int[] mTempExemptAppIds = mPowerExemptAllAppIds;
/**
* Per-user packages that are in the EXEMPT bucket.
*/
@GuardedBy("mLock")
- private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
+ private final SparseSetArray<String> mExemptBucketPackages = new SparseSetArray<>();
@GuardedBy("mLock")
final ArraySet<Listener> mListeners = new ArraySet<>();
@@ -177,10 +177,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
int UID_FG_STATE_CHANGED = 0;
int UID_ACTIVE_STATE_CHANGED = 1;
int RUN_ANY_CHANGED = 2;
- int ALL_UNWHITELISTED = 3;
- int ALL_WHITELIST_CHANGED = 4;
- int TEMP_WHITELIST_CHANGED = 5;
- int EXEMPT_CHANGED = 6;
+ int ALL_UNEXEMPTED = 3;
+ int ALL_EXEMPTION_LIST_CHANGED = 4;
+ int TEMP_EXEMPTION_LIST_CHANGED = 5;
+ int EXEMPT_BUCKET_CHANGED = 6;
int FORCE_ALL_CHANGED = 7;
int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
@@ -192,10 +192,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
"UID_FG_STATE_CHANGED",
"UID_ACTIVE_STATE_CHANGED",
"RUN_ANY_CHANGED",
- "ALL_UNWHITELISTED",
- "ALL_WHITELIST_CHANGED",
- "TEMP_WHITELIST_CHANGED",
- "EXEMPT_CHANGED",
+ "ALL_UNEXEMPTED",
+ "ALL_EXEMPTION_LIST_CHANGED",
+ "TEMP_EXEMPTION_LIST_CHANGED",
+ "EXEMPT_BUCKET_CHANGED",
"FORCE_ALL_CHANGED",
"FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
@@ -308,38 +308,39 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
- * This is called when an app-id(s) is removed from the power save whitelist.
+ * This is called when an app-id(s) is removed from the power save allow-list.
*/
- private void onPowerSaveUnwhitelisted(AppStateTrackerImpl sender) {
+ private void onPowerSaveUnexempted(AppStateTrackerImpl sender) {
updateAllJobs();
unblockAllUnrestrictedAlarms();
}
/**
- * This is called when the power save whitelist changes, excluding the
- * {@link #onPowerSaveUnwhitelisted} case.
+ * This is called when the power save exemption list changes, excluding the
+ * {@link #onPowerSaveUnexempted} case.
*/
- private void onPowerSaveWhitelistedChanged(AppStateTrackerImpl sender) {
+ private void onPowerSaveExemptionListChanged(AppStateTrackerImpl sender) {
updateAllJobs();
}
/**
- * This is called when the temp whitelist changes.
+ * This is called when the temp exemption list changes.
*/
- private void onTempPowerSaveWhitelistChanged(AppStateTrackerImpl sender) {
+ private void onTempPowerSaveExemptionListChanged(AppStateTrackerImpl sender) {
// TODO This case happens rather frequently; consider optimizing and update jobs
// only for affected app-ids.
updateAllJobs();
- // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
+ // Note when an app is just put in the temp exemption list, we do *not* drain pending
+ // alarms.
}
/**
* This is called when the EXEMPT bucket is updated.
*/
- private void onExemptChanged(AppStateTrackerImpl sender) {
+ private void onExemptBucketChanged(AppStateTrackerImpl sender) {
// This doesn't happen very often, so just re-evaluate all jobs / alarms.
updateAllJobs();
unblockAllUnrestrictedAlarms();
@@ -709,8 +710,8 @@ public class AppStateTrackerImpl implements AppStateTracker {
&& !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
final String pkgName = intent.getData().getSchemeSpecificPart();
- if (mExemptedPackages.remove(userId, pkgName)) {
- mHandler.notifyExemptChanged();
+ if (mExemptBucketPackages.remove(userId, pkgName)) {
+ mHandler.notifyExemptBucketChanged();
}
}
}
@@ -727,12 +728,12 @@ public class AppStateTrackerImpl implements AppStateTracker {
synchronized (mLock) {
final boolean changed;
if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
- changed = mExemptedPackages.add(userId, packageName);
+ changed = mExemptBucketPackages.add(userId, packageName);
} else {
- changed = mExemptedPackages.remove(userId, packageName);
+ changed = mExemptBucketPackages.remove(userId, packageName);
}
if (changed) {
- mHandler.notifyExemptChanged();
+ mHandler.notifyExemptBucketChanged();
}
}
}
@@ -748,13 +749,13 @@ public class AppStateTrackerImpl implements AppStateTracker {
private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
private static final int MSG_UID_FG_STATE_CHANGED = 1;
private static final int MSG_RUN_ANY_CHANGED = 3;
- private static final int MSG_ALL_UNWHITELISTED = 4;
- private static final int MSG_ALL_WHITELIST_CHANGED = 5;
- private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
+ private static final int MSG_ALL_UNEXEMPTED = 4;
+ private static final int MSG_ALL_EXEMPTION_LIST_CHANGED = 5;
+ private static final int MSG_TEMP_EXEMPTION_LIST_CHANGED = 6;
private static final int MSG_FORCE_ALL_CHANGED = 7;
private static final int MSG_USER_REMOVED = 8;
private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
- private static final int MSG_EXEMPT_CHANGED = 10;
+ private static final int MSG_EXEMPT_BUCKET_CHANGED = 10;
private static final int MSG_ON_UID_STATE_CHANGED = 11;
private static final int MSG_ON_UID_ACTIVE = 12;
@@ -777,19 +778,19 @@ public class AppStateTrackerImpl implements AppStateTracker {
obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
}
- public void notifyAllUnwhitelisted() {
- removeMessages(MSG_ALL_UNWHITELISTED);
- obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
+ public void notifyAllUnexempted() {
+ removeMessages(MSG_ALL_UNEXEMPTED);
+ obtainMessage(MSG_ALL_UNEXEMPTED).sendToTarget();
}
- public void notifyAllWhitelistChanged() {
- removeMessages(MSG_ALL_WHITELIST_CHANGED);
- obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
+ public void notifyAllExemptionListChanged() {
+ removeMessages(MSG_ALL_EXEMPTION_LIST_CHANGED);
+ obtainMessage(MSG_ALL_EXEMPTION_LIST_CHANGED).sendToTarget();
}
- public void notifyTempWhitelistChanged() {
- removeMessages(MSG_TEMP_WHITELIST_CHANGED);
- obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
+ public void notifyTempExemptionListChanged() {
+ removeMessages(MSG_TEMP_EXEMPTION_LIST_CHANGED);
+ obtainMessage(MSG_TEMP_EXEMPTION_LIST_CHANGED).sendToTarget();
}
public void notifyForceAllAppsStandbyChanged() {
@@ -802,9 +803,9 @@ public class AppStateTrackerImpl implements AppStateTracker {
obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
}
- public void notifyExemptChanged() {
- removeMessages(MSG_EXEMPT_CHANGED);
- obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
+ public void notifyExemptBucketChanged() {
+ removeMessages(MSG_EXEMPT_BUCKET_CHANGED);
+ obtainMessage(MSG_EXEMPT_BUCKET_CHANGED).sendToTarget();
}
public void doUserRemoved(int userId) {
@@ -866,32 +867,32 @@ public class AppStateTrackerImpl implements AppStateTracker {
mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
return;
- case MSG_ALL_UNWHITELISTED:
+ case MSG_ALL_UNEXEMPTED:
for (Listener l : cloneListeners()) {
- l.onPowerSaveUnwhitelisted(sender);
+ l.onPowerSaveUnexempted(sender);
}
- mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
+ mStatLogger.logDurationStat(Stats.ALL_UNEXEMPTED, start);
return;
- case MSG_ALL_WHITELIST_CHANGED:
+ case MSG_ALL_EXEMPTION_LIST_CHANGED:
for (Listener l : cloneListeners()) {
- l.onPowerSaveWhitelistedChanged(sender);
+ l.onPowerSaveExemptionListChanged(sender);
}
- mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
+ mStatLogger.logDurationStat(Stats.ALL_EXEMPTION_LIST_CHANGED, start);
return;
- case MSG_TEMP_WHITELIST_CHANGED:
+ case MSG_TEMP_EXEMPTION_LIST_CHANGED:
for (Listener l : cloneListeners()) {
- l.onTempPowerSaveWhitelistChanged(sender);
+ l.onTempPowerSaveExemptionListChanged(sender);
}
- mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
+ mStatLogger.logDurationStat(Stats.TEMP_EXEMPTION_LIST_CHANGED, start);
return;
- case MSG_EXEMPT_CHANGED:
+ case MSG_EXEMPT_BUCKET_CHANGED:
for (Listener l : cloneListeners()) {
- l.onExemptChanged(sender);
+ l.onExemptBucketChanged(sender);
}
- mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
+ mStatLogger.logDurationStat(Stats.EXEMPT_BUCKET_CHANGED, start);
return;
case MSG_FORCE_ALL_CHANGED:
@@ -1004,7 +1005,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
cleanUpArrayForUser(mActiveUids, removedUserId);
cleanUpArrayForUser(mForegroundUids, removedUserId);
- mExemptedPackages.remove(removedUserId);
+ mExemptBucketPackages.remove(removedUserId);
}
}
@@ -1020,39 +1021,39 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
- * Called by device idle controller to update the power save whitelists.
+ * Called by device idle controller to update the power save exemption lists.
*/
- public void setPowerSaveWhitelistAppIds(
- int[] powerSaveWhitelistExceptIdleAppIdArray,
- int[] powerSaveWhitelistUserAppIdArray,
- int[] tempWhitelistAppIdArray) {
+ public void setPowerSaveExemptionListAppIds(
+ int[] powerSaveExemptionListExceptIdleAppIdArray,
+ int[] powerSaveExemptionListUserAppIdArray,
+ int[] tempExemptionListAppIdArray) {
synchronized (mLock) {
- final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
- final int[] previousTempWhitelist = mTempWhitelistedAppIds;
+ final int[] previousExemptionList = mPowerExemptAllAppIds;
+ final int[] previousTempExemptionList = mTempExemptAppIds;
- mPowerWhitelistedAllAppIds = powerSaveWhitelistExceptIdleAppIdArray;
- mTempWhitelistedAppIds = tempWhitelistAppIdArray;
- mPowerWhitelistedUserAppIds = powerSaveWhitelistUserAppIdArray;
+ mPowerExemptAllAppIds = powerSaveExemptionListExceptIdleAppIdArray;
+ mTempExemptAppIds = tempExemptionListAppIdArray;
+ mPowerExemptUserAppIds = powerSaveExemptionListUserAppIdArray;
- if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
- mHandler.notifyAllUnwhitelisted();
- } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
- mHandler.notifyAllWhitelistChanged();
+ if (isAnyAppIdUnexempt(previousExemptionList, mPowerExemptAllAppIds)) {
+ mHandler.notifyAllUnexempted();
+ } else if (!Arrays.equals(previousExemptionList, mPowerExemptAllAppIds)) {
+ mHandler.notifyAllExemptionListChanged();
}
- if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
- mHandler.notifyTempWhitelistChanged();
+ if (!Arrays.equals(previousTempExemptionList, mTempExemptAppIds)) {
+ mHandler.notifyTempExemptionListChanged();
}
}
}
/**
- * @retunr true if a sorted app-id array {@code prevArray} has at least one element
+ * @return true if a sorted app-id array {@code prevArray} has at least one element
* that's not in a sorted app-id array {@code newArray}.
*/
@VisibleForTesting
- static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
+ static boolean isAnyAppIdUnexempt(int[] prevArray, int[] newArray) {
int i1 = 0;
int i2 = 0;
boolean prevFinished;
@@ -1100,7 +1101,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
*/
public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
boolean isExemptOnBatterySaver) {
- return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
+ return isRestricted(uid, packageName, /*useTempExemptionListToo=*/ false,
isExemptOnBatterySaver);
}
@@ -1109,7 +1110,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
*/
public boolean areJobsRestricted(int uid, @NonNull String packageName,
boolean hasForegroundExemption) {
- return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
+ return isRestricted(uid, packageName, /*useTempExemptionListToo=*/ true,
hasForegroundExemption);
}
@@ -1127,17 +1128,16 @@ public class AppStateTrackerImpl implements AppStateTracker {
* @return whether force-app-standby is effective for a UID package-name.
*/
private boolean isRestricted(int uid, @NonNull String packageName,
- boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
+ boolean useTempExemptionListToo, boolean exemptOnBatterySaver) {
if (isUidActive(uid)) {
return false;
}
synchronized (mLock) {
- // Whitelisted?
final int appId = UserHandle.getAppId(uid);
- if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
+ if (ArrayUtils.contains(mPowerExemptAllAppIds, appId)) {
return false;
}
- if (useTempWhitelistToo && ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
+ if (useTempExemptionListToo && ArrayUtils.contains(mTempExemptAppIds, appId)) {
return false;
}
if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
@@ -1148,7 +1148,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
final int userId = UserHandle.getUserId(uid);
if (mAppStandbyInternal.isAppIdleEnabled() && !mAppStandbyInternal.isInParole()
- && mExemptedPackages.contains(userId, packageName)) {
+ && mExemptBucketPackages.contains(userId, packageName)) {
return false;
}
return mForceAllAppsStandby;
@@ -1225,34 +1225,34 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
- * @return whether a UID is in the user / system defined power-save whitelist or not.
+ * @return whether a UID is in the user / system defined power-save exemption list or not.
*
* Note clients normally shouldn't need to access it. It's only for dumpsys.
*/
- public boolean isUidPowerSaveWhitelisted(int uid) {
+ public boolean isUidPowerSaveExempt(int uid) {
synchronized (mLock) {
- return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
+ return ArrayUtils.contains(mPowerExemptAllAppIds, UserHandle.getAppId(uid));
}
}
/**
* @param uid the uid to check for
- * @return whether a UID is in the user defined power-save whitelist or not.
+ * @return whether a UID is in the user defined power-save exemption list or not.
*/
- public boolean isUidPowerSaveUserWhitelisted(int uid) {
+ public boolean isUidPowerSaveUserExempt(int uid) {
synchronized (mLock) {
- return ArrayUtils.contains(mPowerWhitelistedUserAppIds, UserHandle.getAppId(uid));
+ return ArrayUtils.contains(mPowerExemptUserAppIds, UserHandle.getAppId(uid));
}
}
/**
- * @return whether a UID is in the temp power-save whitelist or not.
+ * @return whether a UID is in the temp power-save exemption list or not.
*
* Note clients normally shouldn't need to access it. It's only for dumpsys.
*/
- public boolean isUidTempPowerSaveWhitelisted(int uid) {
+ public boolean isUidTempPowerSaveExempt(int uid) {
synchronized (mLock) {
- return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
+ return ArrayUtils.contains(mTempExemptAppIds, UserHandle.getAppId(uid));
}
}
@@ -1290,25 +1290,25 @@ public class AppStateTrackerImpl implements AppStateTracker {
pw.print("Foreground uids: ");
dumpUids(pw, mForegroundUids);
- pw.print("Except-idle + user whitelist appids: ");
- pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
+ pw.print("Except-idle + user exemption list appids: ");
+ pw.println(Arrays.toString(mPowerExemptAllAppIds));
- pw.print("User whitelist appids: ");
- pw.println(Arrays.toString(mPowerWhitelistedUserAppIds));
+ pw.print("User exemption list appids: ");
+ pw.println(Arrays.toString(mPowerExemptUserAppIds));
- pw.print("Temp whitelist appids: ");
- pw.println(Arrays.toString(mTempWhitelistedAppIds));
+ pw.print("Temp exemption list appids: ");
+ pw.println(Arrays.toString(mTempExemptAppIds));
- pw.println("Exempted packages:");
+ pw.println("Exempted bucket packages:");
pw.increaseIndent();
- for (int i = 0; i < mExemptedPackages.size(); i++) {
+ for (int i = 0; i < mExemptBucketPackages.size(); i++) {
pw.print("User ");
- pw.print(mExemptedPackages.keyAt(i));
+ pw.print(mExemptBucketPackages.keyAt(i));
pw.println();
pw.increaseIndent();
- for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
- pw.print(mExemptedPackages.valueAt(i, j));
+ for (int j = 0; j < mExemptBucketPackages.sizeAt(i); j++) {
+ pw.print(mExemptBucketPackages.valueAt(i, j));
pw.println();
}
pw.decreaseIndent();
@@ -1372,24 +1372,24 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
}
- for (int appId : mPowerWhitelistedAllAppIds) {
- proto.write(AppStateTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
+ for (int appId : mPowerExemptAllAppIds) {
+ proto.write(AppStateTrackerProto.POWER_SAVE_EXEMPT_APP_IDS, appId);
}
- for (int appId : mPowerWhitelistedUserAppIds) {
- proto.write(AppStateTrackerProto.POWER_SAVE_USER_WHITELIST_APP_IDS, appId);
+ for (int appId : mPowerExemptUserAppIds) {
+ proto.write(AppStateTrackerProto.POWER_SAVE_USER_EXEMPT_APP_IDS, appId);
}
- for (int appId : mTempWhitelistedAppIds) {
- proto.write(AppStateTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
+ for (int appId : mTempExemptAppIds) {
+ proto.write(AppStateTrackerProto.TEMP_POWER_SAVE_EXEMPT_APP_IDS, appId);
}
- for (int i = 0; i < mExemptedPackages.size(); i++) {
- for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
- final long token2 = proto.start(AppStateTrackerProto.EXEMPTED_PACKAGES);
+ for (int i = 0; i < mExemptBucketPackages.size(); i++) {
+ for (int j = 0; j < mExemptBucketPackages.sizeAt(i); j++) {
+ final long token2 = proto.start(AppStateTrackerProto.EXEMPTED_BUCKET_PACKAGES);
- proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
- proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
+ proto.write(ExemptedPackage.USER_ID, mExemptBucketPackages.keyAt(i));
+ proto.write(ExemptedPackage.PACKAGE_NAME, mExemptBucketPackages.valueAt(i, j));
proto.end(token2);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index b1bafeea3c98..6c3398f91db1 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -3715,7 +3715,7 @@ public class DeviceIdleController extends SystemService
}
private void passWhiteListsToForceAppStandbyTrackerLocked() {
- mAppStateTracker.setPowerSaveWhitelistAppIds(
+ mAppStateTracker.setPowerSaveExemptionListAppIds(
mPowerSaveWhitelistExceptIdleAppIdArray,
mPowerSaveWhitelistUserAppIdArray,
mTempWhitelistAppIdArray);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 6529503808b3..4194fd0068c2 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2089,7 +2089,7 @@ public class AlarmManagerService extends SystemService {
} else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
|| UserHandle.isSameApp(callingUid, mSystemUiUid)
|| ((mAppStateTracker != null)
- && mAppStateTracker.isUidPowerSaveUserWhitelisted(callingUid)))) {
+ && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 06c469a5cc82..3234b274eaa7 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -89,6 +89,7 @@ import com.android.server.AppStateTracker;
import com.android.server.AppStateTrackerImpl;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
+import com.android.server.SystemService.TargetUser;
import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
import com.android.server.job.controllers.BackgroundJobsController;
@@ -975,24 +976,24 @@ public class JobSchedulerService extends com.android.server.SystemService
}
@Override
- public void onStartUser(int userHandle) {
+ public void onUserStarting(@NonNull TargetUser user) {
synchronized (mLock) {
- mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userHandle);
+ mStartedUsers = ArrayUtils.appendInt(mStartedUsers, user.getUserIdentifier());
}
// Let's kick any outstanding jobs for this user.
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
}
@Override
- public void onUnlockUser(int userHandle) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
// Let's kick any outstanding jobs for this user.
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
}
@Override
- public void onStopUser(int userHandle) {
+ public void onUserStopping(@NonNull TargetUser user) {
synchronized (mLock) {
- mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userHandle);
+ mStartedUsers = ArrayUtils.removeInt(mStartedUsers, user.getUserIdentifier());
}
}
@@ -1193,7 +1194,7 @@ public class JobSchedulerService extends com.android.server.SystemService
private void cancelJobsForNonExistentUsers() {
UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
synchronized (mLock) {
- mJobs.removeJobsOfNonUsers(umi.getUserIds());
+ mJobs.removeJobsOfUnlistedUsers(umi.getUserIds());
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index 7bd51b77a119..eaf8f4d96331 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -254,11 +254,11 @@ public final class JobStore {
}
/**
- * Remove the jobs of users not specified in the whitelist.
- * @param whitelist Array of User IDs whose jobs are not to be removed.
+ * Remove the jobs of users not specified in the keepUserIds.
+ * @param keepUserIds Array of User IDs whose jobs should be kept and not removed.
*/
- public void removeJobsOfNonUsers(int[] whitelist) {
- mJobSet.removeJobsOfNonUsers(whitelist);
+ public void removeJobsOfUnlistedUsers(int[] keepUserIds) {
+ mJobSet.removeJobsOfUnlistedUsers(keepUserIds);
}
@VisibleForTesting
@@ -1151,15 +1151,14 @@ public final class JobStore {
}
/**
- * Removes the jobs of all users not specified by the whitelist of user ids.
- * This will remove jobs scheduled *by* non-existent users as well as jobs scheduled *for*
- * non-existent users
+ * Removes the jobs of all users not specified by the keepUserIds of user ids.
+ * This will remove jobs scheduled *by* and *for* any unlisted users.
*/
- public void removeJobsOfNonUsers(final int[] whitelist) {
+ public void removeJobsOfUnlistedUsers(final int[] keepUserIds) {
final Predicate<JobStatus> noSourceUser =
- job -> !ArrayUtils.contains(whitelist, job.getSourceUserId());
+ job -> !ArrayUtils.contains(keepUserIds, job.getSourceUserId());
final Predicate<JobStatus> noCallingUser =
- job -> !ArrayUtils.contains(whitelist, job.getUserId());
+ job -> !ArrayUtils.contains(keepUserIds, job.getUserId());
removeAll(noSourceUser.or(noCallingUser));
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
index b6324358ec33..44c8fcff8c63 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
@@ -91,9 +91,9 @@ public final class BackgroundJobsController extends StateController {
pw.print(" from ");
UserHandle.formatUid(pw, uid);
pw.print(mAppStateTracker.isUidActive(uid) ? " active" : " idle");
- if (mAppStateTracker.isUidPowerSaveWhitelisted(uid) ||
- mAppStateTracker.isUidTempPowerSaveWhitelisted(uid)) {
- pw.print(", whitelisted");
+ if (mAppStateTracker.isUidPowerSaveExempt(uid)
+ || mAppStateTracker.isUidTempPowerSaveExempt(uid)) {
+ pw.print(", exempted");
}
pw.print(": ");
pw.print(sourcePkg);
@@ -132,8 +132,8 @@ public final class BackgroundJobsController extends StateController {
proto.write(TrackedJob.IS_IN_FOREGROUND, mAppStateTracker.isUidActive(sourceUid));
proto.write(TrackedJob.IS_WHITELISTED,
- mAppStateTracker.isUidPowerSaveWhitelisted(sourceUid) ||
- mAppStateTracker.isUidTempPowerSaveWhitelisted(sourceUid));
+ mAppStateTracker.isUidPowerSaveExempt(sourceUid)
+ || mAppStateTracker.isUidTempPowerSaveExempt(sourceUid));
proto.write(TrackedJob.CAN_RUN_ANY_IN_BACKGROUND,
mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(sourceUid, sourcePkg));
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 2f993dad51c7..6bc95bf8bc75 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -222,12 +222,19 @@ public class AppStandbyController implements AppStandbyInternal {
@GuardedBy("mPackageAccessListeners")
private final ArrayList<AppIdleStateChangeListener> mPackageAccessListeners = new ArrayList<>();
+ /**
+ * Lock specifically for bookkeeping around the carrier-privileged app set.
+ * Do not acquire any other locks while holding this one. Methods that
+ * require this lock to be held are named with a "CPL" suffix.
+ */
+ private final Object mCarrierPrivilegedLock = new Lock();
+
/** Whether we've queried the list of carrier privileged apps. */
- @GuardedBy("mAppIdleLock")
+ @GuardedBy("mCarrierPrivilegedLock")
private boolean mHaveCarrierPrivilegedApps;
/** List of carrier-privileged apps that should be excluded from standby */
- @GuardedBy("mAppIdleLock")
+ @GuardedBy("mCarrierPrivilegedLock")
private List<String> mCarrierPrivilegedApps;
@GuardedBy("mActiveAdminApps")
@@ -1594,9 +1601,9 @@ public class AppStandbyController implements AppStandbyInternal {
}
private boolean isCarrierApp(String packageName) {
- synchronized (mAppIdleLock) {
+ synchronized (mCarrierPrivilegedLock) {
if (!mHaveCarrierPrivilegedApps) {
- fetchCarrierPrivilegedAppsLocked();
+ fetchCarrierPrivilegedAppsCPL();
}
if (mCarrierPrivilegedApps != null) {
return mCarrierPrivilegedApps.contains(packageName);
@@ -1610,14 +1617,14 @@ public class AppStandbyController implements AppStandbyInternal {
if (DEBUG) {
Slog.i(TAG, "Clearing carrier privileged apps list");
}
- synchronized (mAppIdleLock) {
+ synchronized (mCarrierPrivilegedLock) {
mHaveCarrierPrivilegedApps = false;
mCarrierPrivilegedApps = null; // Need to be refetched.
}
}
- @GuardedBy("mAppIdleLock")
- private void fetchCarrierPrivilegedAppsLocked() {
+ @GuardedBy("mCarrierPrivilegedLock")
+ private void fetchCarrierPrivilegedAppsCPL() {
TelephonyManager telephonyManager =
mContext.getSystemService(TelephonyManager.class);
mCarrierPrivilegedApps =
@@ -1858,7 +1865,7 @@ public class AppStandbyController implements AppStandbyInternal {
@Override
public void dumpState(String[] args, PrintWriter pw) {
- synchronized (mAppIdleLock) {
+ synchronized (mCarrierPrivilegedLock) {
pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps
+ "): " + mCarrierPrivilegedApps);
}
diff --git a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
index 5cdb3249501b..d56a4bd0a8e5 100644
--- a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
+++ b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
@@ -27,17 +27,6 @@ interface IStatsCompanionService {
oneway void statsdReady();
/**
- * Register an alarm for anomaly detection to fire at the given timestamp (ms since epoch).
- * If anomaly alarm had already been registered, it will be replaced with the new timestamp.
- * Uses AlarmManager.set API, so if the timestamp is in the past, alarm fires immediately, and
- * alarm is inexact.
- */
- oneway void setAnomalyAlarm(long timestampMs);
-
- /** Cancel any anomaly detection alarm. */
- oneway void cancelAnomalyAlarm();
-
- /**
* Register a repeating alarm for pulling to fire at the given timestamp and every
* intervalMs thereafter (in ms since epoch).
* If polling alarm had already been registered, it will be replaced by new one.
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
index 0d3f4208a2ab..066412a9f157 100644
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ b/apex/statsd/aidl/android/os/IStatsd.aidl
@@ -42,13 +42,6 @@ interface IStatsd {
void statsCompanionReady();
/**
- * Tells statsd that an anomaly may have occurred, so statsd can check whether this is so and
- * act accordingly.
- * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
- */
- void informAnomalyAlarmFired();
-
- /**
* Tells statsd that it is time to poll some stats. Statsd will be responsible for determing
* what stats to poll and initiating the polling.
* Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index cbc8ed636ff2..b5e72247a4a3 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -100,7 +100,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private static IStatsd sStatsd;
private static final Object sStatsdLock = new Object();
- private final OnAlarmListener mAnomalyAlarmListener;
private final OnAlarmListener mPullingAlarmListener;
private final OnAlarmListener mPeriodicAlarmListener;
@@ -124,7 +123,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
handlerThread.start();
mHandler = new CompanionHandler(handlerThread.getLooper());
- mAnomalyAlarmListener = new AnomalyAlarmListener(context);
mPullingAlarmListener = new PullingAlarmListener(context);
mPeriodicAlarmListener = new PeriodicAlarmListener(context);
}
@@ -336,41 +334,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
- public static final class AnomalyAlarmListener implements OnAlarmListener {
- private final Context mContext;
-
- AnomalyAlarmListener(Context context) {
- mContext = context;
- }
-
- @Override
- public void onAlarm() {
- if (DEBUG) {
- Log.i(TAG, "StatsCompanionService believes an anomaly has occurred at time "
- + System.currentTimeMillis() + "ms.");
- }
- IStatsd statsd = getStatsdNonblocking();
- if (statsd == null) {
- Log.w(TAG, "Could not access statsd to inform it of anomaly alarm firing");
- return;
- }
-
- // Wakelock needs to be retained while calling statsd.
- Thread thread = new WakelockThread(mContext,
- AnomalyAlarmListener.class.getCanonicalName(), new Runnable() {
- @Override
- public void run() {
- try {
- statsd.informAnomalyAlarmFired();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to inform statsd of anomaly alarm firing", e);
- }
- }
- });
- thread.start();
- }
- }
-
public final static class PullingAlarmListener implements OnAlarmListener {
private final Context mContext;
@@ -469,34 +432,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
@Override // Binder call
- public void setAnomalyAlarm(long timestampMs) {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) Log.d(TAG, "Setting anomaly alarm for " + timestampMs);
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
- // only fire when it awakens.
- // AlarmManager will automatically cancel any previous mAnomalyAlarmListener alarm.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".anomaly",
- mAnomalyAlarmListener, mHandler);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
- public void cancelAnomalyAlarm() {
- StatsCompanion.enforceStatsdCallingUid();
- if (DEBUG) Log.d(TAG, "Cancelling anomaly alarm");
- final long callingToken = Binder.clearCallingIdentity();
- try {
- mAlarmManager.cancel(mAnomalyAlarmListener);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- @Override // Binder call
public void setAlarmForSubscriberTriggering(long timestampMs) {
StatsCompanion.enforceStatsdCallingUid();
if (DEBUG) {
@@ -666,7 +601,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
// instead of in binder death because statsd can come back and set different alarms, or not
// want to set an alarm when it had been set. This guarantees that when we get a new statsd,
// we cancel any alarms before it is able to set them.
- cancelAnomalyAlarm();
cancelPullingAlarm();
cancelAlarmForSubscriberTriggering();
diff --git a/api/current.txt b/api/current.txt
index a59c7b85e608..09de005c008c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24207,6 +24207,7 @@ package android.media {
method @NonNull public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations();
method @NonNull public java.util.List<android.media.AudioRecordingConfiguration> getActiveRecordingConfigurations();
method public int getAllowedCapturePolicy();
+ method public int getAudioHwSyncForSession(int);
method public android.media.AudioDeviceInfo[] getDevices(int);
method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
method public int getMode();
@@ -47864,6 +47865,7 @@ package android.telephony {
method @Nullable public android.net.LinkProperties getLinkProperties();
method public int getNetworkType();
method public int getState();
+ method public int getTransportType();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
}
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 696e02972c23..3f3b8eaffdab 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -31,6 +31,14 @@ package android.graphics {
}
+package android.media {
+
+ public class AudioManager {
+ field public static final int FLAG_FROM_KEY = 4096; // 0x1000
+ }
+
+}
+
package android.net {
public final class TetheringConstants {
diff --git a/api/system-current.txt b/api/system-current.txt
index 11db781dd42f..56059dd9d864 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4201,6 +4201,7 @@ package android.media {
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) public long getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -4219,6 +4220,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
@@ -4229,6 +4231,11 @@ package android.media {
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
+ field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+ field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
+ field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
+ field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
+ field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
field public static final int SUCCESS = 0; // 0x0
}
@@ -10838,6 +10845,7 @@ package android.telephony {
method @Deprecated public int getDataConnectionApnTypeBitMask();
method @Deprecated public int getDataConnectionFailCause();
method @Deprecated public int getDataConnectionState();
+ method public int getId();
}
public final class PreciseDisconnectCause {
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
index 02b27a8800b6..403d8c55de16 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
@@ -29,4 +29,5 @@ interface OverlayablePolicy {
const int ODM_PARTITION = 0x00000020;
const int OEM_PARTITION = 0x00000040;
const int ACTOR_SIGNATURE = 0x00000080;
+ const int CONFIG_SIGNATURE = 0x0000100;
}
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index 34589a1c39dc..fd8b4eb86b4a 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -61,10 +61,13 @@ Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
const ResourceId& target_resource) {
static constexpr const PolicyBitmask sDefaultPolicies =
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
- PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;
+ PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
+ PolicyFlags::CONFIG_SIGNATURE;
// If the resource does not have an overlayable definition, allow the resource to be overlaid if
- // the overlay is preinstalled or signed with the same signature as the target.
+ // the overlay is preinstalled, signed with the same signature as the target or signed with the
+ // same signature as reference package defined in SystemConfig under 'overlay-config-signature'
+ // tag.
if (!target_package.DefinesOverlayable()) {
return (sDefaultPolicies & fulfilled_policies) != 0
? Result<Unit>({})
diff --git a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
index f7987b01fe9e..cdce45191094 100644
--- a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
+++ b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
@@ -38,16 +38,18 @@ constexpr const char* kPolicyOdm = "odm";
constexpr const char* kPolicyOem = "oem";
constexpr const char* kPolicyProduct = "product";
constexpr const char* kPolicyPublic = "public";
+constexpr const char* kPolicyConfigSignature = "config_signature";
constexpr const char* kPolicySignature = "signature";
constexpr const char* kPolicySystem = "system";
constexpr const char* kPolicyVendor = "vendor";
-inline static const std::array<std::pair<StringPiece, PolicyFlags>, 8> kPolicyStringToFlag = {
+inline static const std::array<std::pair<StringPiece, PolicyFlags>, 9> kPolicyStringToFlag = {
std::pair{kPolicyActor, PolicyFlags::ACTOR_SIGNATURE},
{kPolicyOdm, PolicyFlags::ODM_PARTITION},
{kPolicyOem, PolicyFlags::OEM_PARTITION},
{kPolicyProduct, PolicyFlags::PRODUCT_PARTITION},
{kPolicyPublic, PolicyFlags::PUBLIC},
+ {kPolicyConfigSignature, PolicyFlags::CONFIG_SIGNATURE},
{kPolicySignature, PolicyFlags::SIGNATURE},
{kPolicySystem, PolicyFlags::SYSTEM_PARTITION},
{kPolicyVendor, PolicyFlags::VENDOR_PARTITION},
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index 4f2ee1c4880a..854b57fb22aa 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -43,16 +43,17 @@ namespace R::target {
constexpr ResourceId not_overlayable = 0x7f020003;
constexpr ResourceId other = 0x7f020004;
constexpr ResourceId policy_actor = 0x7f020005;
- constexpr ResourceId policy_odm = 0x7f020006;
- constexpr ResourceId policy_oem = 0x7f020007;
- constexpr ResourceId policy_product = 0x7f020008;
- constexpr ResourceId policy_public = 0x7f020009;
- constexpr ResourceId policy_signature = 0x7f02000a;
- constexpr ResourceId policy_system = 0x7f02000b;
- constexpr ResourceId policy_system_vendor = 0x7f02000c;
- constexpr ResourceId str1 = 0x7f02000d;
- constexpr ResourceId str3 = 0x7f02000f;
- constexpr ResourceId str4 = 0x7f020010;
+ constexpr ResourceId policy_config_signature = 0x7f020006;
+ constexpr ResourceId policy_odm = 0x7f020007;
+ constexpr ResourceId policy_oem = 0x7f020008;
+ constexpr ResourceId policy_product = 0x7f020009;
+ constexpr ResourceId policy_public = 0x7f02000a;
+ constexpr ResourceId policy_signature = 0x7f02000b;
+ constexpr ResourceId policy_system = 0x7f02000c;
+ constexpr ResourceId policy_system_vendor = 0x7f02000d;
+ constexpr ResourceId str1 = 0x7f02000e;
+ constexpr ResourceId str3 = 0x7f020010;
+ constexpr ResourceId str4 = 0x7f020011;
namespace literal { // NOLINT(runtime/indentation_namespace)
inline const std::string str1 = hexify(R::target::string::str1);
@@ -94,13 +95,14 @@ namespace R::system_overlay_invalid::string {
constexpr ResourceId not_overlayable = 0x7f010000;
constexpr ResourceId other = 0x7f010001;
constexpr ResourceId policy_actor = 0x7f010002;
- constexpr ResourceId policy_odm = 0x7f010003;
- constexpr ResourceId policy_oem = 0x7f010004;
- constexpr ResourceId policy_product = 0x7f010005;
- constexpr ResourceId policy_public = 0x7f010006;
- constexpr ResourceId policy_signature = 0x7f010007;
- constexpr ResourceId policy_system = 0x7f010008;
- constexpr ResourceId policy_system_vendor = 0x7f010009;
+ constexpr ResourceId policy_config_signature = 0x7f010003;
+ constexpr ResourceId policy_odm = 0x7f010004;
+ constexpr ResourceId policy_oem = 0x7f010005;
+ constexpr ResourceId policy_product = 0x7f010006;
+ constexpr ResourceId policy_public = 0x7f010007;
+ constexpr ResourceId policy_signature = 0x7f010008;
+ constexpr ResourceId policy_system = 0x7f010009;
+ constexpr ResourceId policy_system_vendor = 0x7f01000a;
} // namespace R::system_overlay_invalid::string
// clang-format on
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index de039f440e33..3ec6ac24b238 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -237,7 +237,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(res.GetTargetToOverlayMap().size(), 10U);
+ ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U);
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
@@ -256,6 +256,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
+ Res_value::TYPE_REFERENCE,
+ R::system_overlay_invalid::string::policy_config_signature,
+ false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_signature,
false /* rewrite */));
@@ -298,8 +302,9 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
}
-// Overlays that are pre-installed or are signed with the same signature as the target can overlay
-// packages that have not defined overlayable resources.
+// Overlays that are pre-installed or are signed with the same signature as the target or are signed
+// with the same signature as the reference package can overlay packages that have not defined
+// overlayable resources.
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
@@ -309,7 +314,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
+ ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U);
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
@@ -330,6 +335,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_public,
false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
+ Res_value::TYPE_REFERENCE,
+ R::system_overlay_invalid::string::policy_config_signature,
+ false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_signature,
false /* rewrite */));
@@ -342,6 +351,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
};
CheckEntries(PolicyFlags::SIGNATURE);
+ CheckEntries(PolicyFlags::CONFIG_SIGNATURE);
CheckEntries(PolicyFlags::PRODUCT_PARTITION);
CheckEntries(PolicyFlags::SYSTEM_PARTITION);
CheckEntries(PolicyFlags::VENDOR_PARTITION);
diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h
index 74ea18f88648..9641f6b55670 100644
--- a/cmds/idmap2/tests/TestConstants.h
+++ b/cmds/idmap2/tests/TestConstants.h
@@ -19,11 +19,11 @@
namespace android::idmap2::TestConstants {
-constexpr const auto TARGET_CRC = 0x41c60c8c;
-constexpr const auto TARGET_CRC_STRING = "41c60c8c";
+constexpr const auto TARGET_CRC = 0x7c2d4719;
+constexpr const auto TARGET_CRC_STRING = "7c2d4719";
-constexpr const auto OVERLAY_CRC = 0xc054fb26;
-constexpr const auto OVERLAY_CRC_STRING = "c054fb26";
+constexpr const auto OVERLAY_CRC = 0x5afff726;
+constexpr const auto OVERLAY_CRC_STRING = "5afff726";
} // namespace android::idmap2::TestConstants
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
index 7c25985e5a61..dab25b1f8131 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
index c75f3e1dbddf..c8b95c2601ad 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-shared.apk b/cmds/idmap2/tests/data/overlay/overlay-shared.apk
index 93dcc82f9358..0a8b7372172e 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-shared.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-shared.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
index 5b8a6e4a90ed..fd41182f8493 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
index 698a1fd6e702..b24765fc666a 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk
index 1db303ff05b5..870575efa10c 100644
--- a/cmds/idmap2/tests/data/overlay/overlay.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
index 51e19de082ed..e0fd20499671 100644
--- a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
+++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
index 7119d8283061..ebaf49c34762 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
@@ -26,6 +26,7 @@
<string name="policy_odm">policy_odm</string>
<string name="policy_oem">policy_oem</string>
<string name="policy_actor">policy_actor</string>
+ <string name="policy_config_signature">policy_config_signature</string>
<!-- Requests to overlay a resource that is not declared as overlayable. -->
<string name="not_overlayable">not_overlayable</string>
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
index bd990983693c..a63daf86caf5 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
index a0fba4378b57..90d2803a1eca 100644
--- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
+++ b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
index ad4cd4882632..57e6c439c23c 100644
--- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml
+++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
@@ -45,6 +45,10 @@
<item type="string" name="policy_actor" />
</policy>
+ <policy type="config_signature">
+ <item type="string" name="policy_config_signature"/>
+ </policy>
+
<!-- Resources publicly overlayable -->
<policy type="public">
<item type="string" name="policy_public" />
diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml
index 5230e25e626b..00909a9e481c 100644
--- a/cmds/idmap2/tests/data/target/res/values/values.xml
+++ b/cmds/idmap2/tests/data/target/res/values/values.xml
@@ -37,6 +37,7 @@
<string name="policy_system">policy_system</string>
<string name="policy_system_vendor">policy_system_vendor</string>
<string name="policy_actor">policy_actor</string>
+ <string name="policy_config_signature">policy_config_signature</string>
<string name="other">other</string>
</resources>
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
index 58504a74a83a..cc3491de894d 100644
--- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk
index c80e5eb65ff2..4a58c5e28f49 100644
--- a/cmds/idmap2/tests/data/target/target.apk
+++ b/cmds/idmap2/tests/data/target/target.apk
Binary files differ
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index c1d8399d91a5..a46a54cc2063 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -182,16 +182,17 @@ int main(int argc, char** argv)
ProcessState::self()->setThreadPoolMaxThreadCount(0);
ProcessState::self()->startThreadPool();
- ui::Dataspace outDataspace;
- sp<GraphicBuffer> outBuffer;
-
- status_t result = ScreenshotClient::capture(*displayId, &outDataspace, &outBuffer);
+ ScreenCaptureResults captureResults;
+ status_t result = ScreenshotClient::captureDisplay(*displayId, captureResults);
if (result != NO_ERROR) {
close(fd);
return 1;
}
- result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
+ ui::Dataspace dataspace = captureResults.capturedDataspace;
+ sp<GraphicBuffer> buffer = captureResults.buffer;
+
+ result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
if (base == nullptr || result != NO_ERROR) {
String8 reason;
@@ -207,13 +208,13 @@ int main(int argc, char** argv)
if (png) {
AndroidBitmapInfo info;
- info.format = flinger2bitmapFormat(outBuffer->getPixelFormat());
+ info.format = flinger2bitmapFormat(buffer->getPixelFormat());
info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
- info.width = outBuffer->getWidth();
- info.height = outBuffer->getHeight();
- info.stride = outBuffer->getStride() * bytesPerPixel(outBuffer->getPixelFormat());
+ info.width = buffer->getWidth();
+ info.height = buffer->getHeight();
+ info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
- int result = AndroidBitmap_compress(&info, static_cast<int32_t>(outDataspace), base,
+ int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
[](void* fdPtr, const void* data, size_t size) -> bool {
int bytesWritten = write(*static_cast<int*>(fdPtr),
@@ -229,11 +230,11 @@ int main(int argc, char** argv)
notifyMediaScanner(fn);
}
} else {
- uint32_t w = outBuffer->getWidth();
- uint32_t h = outBuffer->getHeight();
- uint32_t s = outBuffer->getStride();
- uint32_t f = outBuffer->getPixelFormat();
- uint32_t c = dataSpaceToInt(outDataspace);
+ uint32_t w = buffer->getWidth();
+ uint32_t h = buffer->getHeight();
+ uint32_t s = buffer->getStride();
+ uint32_t f = buffer->getPixelFormat();
+ uint32_t c = dataSpaceToInt(dataspace);
write(fd, &w, 4);
write(fd, &h, 4);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 05e9ec3a1769..6327490b0b71 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -120,10 +120,9 @@ static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outDat
}
}
-void StatsLogProcessor::onAnomalyAlarmFired(
+void StatsLogProcessor::processFiredAnomalyAlarmsLocked(
const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
for (const auto& itr : mMetricsManagers) {
itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
}
@@ -429,6 +428,20 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
return;
}
+ bool fireAlarm = false;
+ {
+ std::lock_guard<std::mutex> anomalyLock(mAnomalyAlarmMutex);
+ if (mNextAnomalyAlarmTime != 0 &&
+ MillisToNano(mNextAnomalyAlarmTime) <= elapsedRealtimeNs) {
+ mNextAnomalyAlarmTime = 0;
+ VLOG("informing anomaly alarm at time %lld", (long long)elapsedRealtimeNs);
+ fireAlarm = true;
+ }
+ }
+ if (fireAlarm) {
+ informAnomalyAlarmFiredLocked(NanoToMillis(elapsedRealtimeNs));
+ }
+
int64_t curTimeSec = getElapsedRealtimeSec();
if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
@@ -513,19 +526,34 @@ void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigK
OnConfigUpdatedLocked(timestampNs, key, config);
}
-void StatsLogProcessor::OnConfigUpdatedLocked(
- const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
+void StatsLogProcessor::OnConfigUpdatedLocked(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config, bool modularUpdate) {
VLOG("Updated configuration for key %s", key.ToString().c_str());
- sp<MetricsManager> newMetricsManager =
- new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
- mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
- if (newMetricsManager->isConfigValid()) {
- newMetricsManager->init();
- mUidMap->OnConfigUpdated(key);
- newMetricsManager->refreshTtl(timestampNs);
- mMetricsManagers[key] = newMetricsManager;
- VLOG("StatsdConfig valid");
+ // Create new config if this is not a modular update or if this is a new config.
+ const auto& it = mMetricsManagers.find(key);
+ bool configValid = false;
+ if (!modularUpdate || it == mMetricsManagers.end()) {
+ sp<MetricsManager> newMetricsManager =
+ new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
+ mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
+ configValid = newMetricsManager->isConfigValid();
+ if (configValid) {
+ newMetricsManager->init();
+ mUidMap->OnConfigUpdated(key);
+ newMetricsManager->refreshTtl(timestampNs);
+ mMetricsManagers[key] = newMetricsManager;
+ VLOG("StatsdConfig valid");
+ }
} else {
+ // Preserve the existing MetricsManager, update necessary components and metadata in place.
+ configValid = it->second->updateConfig(timestampNs, config);
+ if (configValid) {
+ // TODO(b/162323476): refresh TTL, ensure init() is handled properly.
+ mUidMap->OnConfigUpdated(key);
+
+ }
+ }
+ if (!configValid) {
// If there is any error in the config, don't use it.
// Remove any existing config with the same key.
ALOGE("StatsdConfig NOT valid");
@@ -1090,6 +1118,28 @@ void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) {
mOnDiskDataConfigs.insert(key);
}
+void StatsLogProcessor::setAnomalyAlarm(const int64_t elapsedTimeMillis) {
+ std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
+ mNextAnomalyAlarmTime = elapsedTimeMillis;
+}
+
+void StatsLogProcessor::cancelAnomalyAlarm() {
+ std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
+ mNextAnomalyAlarmTime = 0;
+}
+
+void StatsLogProcessor::informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis) {
+ VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
+ std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
+ mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(elapsedTimeMillis / 1000));
+ if (alarmSet.size() > 0) {
+ VLOG("Found periodic alarm fired.");
+ processFiredAnomalyAlarmsLocked(MillisToNano(elapsedTimeMillis), alarmSet);
+ } else {
+ ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index c0f54a0995ac..383dbd9db2c1 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -66,11 +66,6 @@ public:
const DumpLatency dumpLatency,
ProtoOutputStream* proto);
- /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
- void onAnomalyAlarmFired(
- const int64_t& timestampNs,
- unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
void onPeriodicAlarmFired(
const int64_t& timestampNs,
@@ -146,6 +141,10 @@ public:
// Add a specific config key to the possible configs to dump ASAP.
void noteOnDiskData(const ConfigKey& key);
+ void setAnomalyAlarm(const int64_t timeMillis);
+
+ void cancelAnomalyAlarm();
+
private:
// For testing only.
inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
@@ -158,6 +157,11 @@ private:
mutable mutex mMetricsMutex;
+ // Guards mNextAnomalyAlarmTime. A separate mutex is needed because alarms are set/cancelled
+ // in the onLogEvent code path, which is locked by mMetricsMutex.
+ // DO NOT acquire mMetricsMutex while holding mAnomalyAlarmMutex. This can lead to a deadlock.
+ mutable mutex mAnomalyAlarmMutex;
+
std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes;
@@ -183,8 +187,8 @@ private:
void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
- void OnConfigUpdatedLocked(
- const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
+ void OnConfigUpdatedLocked(const int64_t currentTimestampNs, const ConfigKey& key,
+ const StatsdConfig& config, bool modularUpdate = false);
void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
@@ -248,6 +252,15 @@ private:
// Reset the specified configs.
void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
+ // An anomaly alarm should have fired.
+ // Check with anomaly alarm manager to find the alarms and process the result.
+ void informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis);
+
+ /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
+ void processFiredAnomalyAlarmsLocked(
+ const int64_t& timestampNs,
+ unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
+
// Function used to send a broadcast so that receiver for the config key can call getData
// to retrieve the stored data.
std::function<bool(const ConfigKey& key)> mSendBroadcast;
@@ -274,6 +287,9 @@ private:
//Last time we wrote metadata to disk.
int64_t mLastMetadataWriteNs = 0;
+ // The time for the next anomaly alarm for alerts.
+ int64_t mNextAnomalyAlarmTime = 0;
+
bool mPrintAllLogs = false;
FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index d5e331495164..68c2dd56ef13 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -91,17 +91,13 @@ Status checkUid(uid_t expectedUid) {
StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
: mAnomalyAlarmMonitor(new AlarmMonitor(
MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
- [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
- if (sc != nullptr) {
- sc->setAnomalyAlarm(timeMillis);
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- }
+ [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) {
+ mProcessor->setAnomalyAlarm(timeMillis);
+ StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
},
- [](const shared_ptr<IStatsCompanionService>& sc) {
- if (sc != nullptr) {
- sc->cancelAnomalyAlarm();
- StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
- }
+ [this](const shared_ptr<IStatsCompanionService>& /*sc*/) {
+ mProcessor->cancelAnomalyAlarm();
+ StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
})),
mPeriodicAlarmMonitor(new AlarmMonitor(
MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
@@ -977,22 +973,6 @@ Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
return Status::ok();
}
-Status StatsService::informAnomalyAlarmFired() {
- ENFORCE_UID(AID_SYSTEM);
-
- VLOG("StatsService::informAnomalyAlarmFired was called");
- int64_t currentTimeSec = getElapsedRealtimeSec();
- std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
- mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
- if (alarmSet.size() > 0) {
- VLOG("Found an anomaly alarm that fired.");
- mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
- } else {
- VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled.");
- }
- return Status::ok();
-}
-
Status StatsService::informAlarmForSubscriberTriggeringFired() {
ENFORCE_UID(AID_SYSTEM);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 324ffbd65e51..479f4e87ec96 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -66,7 +66,6 @@ public:
virtual Status systemRunning();
virtual Status statsCompanionReady();
virtual Status bootCompleted();
- virtual Status informAnomalyAlarmFired();
virtual Status informPollAlarmFired();
virtual Status informAlarmForSubscriberTriggeringFired();
@@ -404,6 +403,10 @@ private:
FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket);
FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket);
FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket);
+
+ FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
+ FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
+ FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
};
} // namespace statsd
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e70eac88c769..c95f4c07f86c 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -66,7 +66,7 @@ import "frameworks/base/core/proto/android/stats/textclassifier/textclassifier_e
import "frameworks/base/core/proto/android/stats/otaupdate/updateengine_enums.proto";
/**
- * The master atom class. This message defines all of the available
+ * The primary atom class. This message defines all of the available
* raw stats log events from the Android system, also known as "atoms."
*
* This field contains a single oneof with all of the available messages.
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index bbae3fef7934..13020e06dc5d 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -128,7 +128,7 @@ void ConfigManager::Startup() {
}
void ConfigManager::StartupForTest() {
- // Dummy function to avoid reading configs from disks for tests.
+ // No-op function to avoid reading configs from disks for tests.
}
void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index 40146b1b2bec..bef057f96409 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -46,7 +46,7 @@ public:
void Startup();
/*
- * Dummy initializer for tests.
+ * No-op initializer for tests.
*/
void StartupForTest();
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 60de1a24cce5..189d8117ae55 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -195,6 +195,10 @@ MetricsManager::~MetricsManager() {
VLOG("~MetricsManager()");
}
+bool MetricsManager::updateConfig(const int64_t currentTimeNs, const StatsdConfig& config) {
+ return mConfigValid;
+}
+
void MetricsManager::initLogSourceWhiteList() {
std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
mAllowedLogSources.clear();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index ad30a88c5d19..042de29e173d 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -46,6 +46,8 @@ public:
virtual ~MetricsManager();
+ bool updateConfig(const int64_t currentTimeNs, const StatsdConfig& config);
+
// Return whether the configuration is valid.
bool isConfigValid() const;
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
index 6c50a8c41770..1bc84c5433f9 100644
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ b/cmds/statsd/src/packages/PackageInfoListener.h
@@ -17,6 +17,8 @@
#ifndef STATSD_PACKAGE_INFO_LISTENER_H
#define STATSD_PACKAGE_INFO_LISTENER_H
+#include <utils/RefBase.h>
+
#include <string>
namespace android {
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 22250aee402e..622321b804ec 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -17,7 +17,6 @@
#pragma once
#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
#include "packages/PackageInfoListener.h"
#include "stats_util.h"
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
index 95e301002a1b..70e7365ec238 100644
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
@@ -12,14 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <android/binder_ibinder.h>
+#include <android/binder_interface_utils.h>
#include <gtest/gtest.h>
-#include "src/anomaly/DurationAnomalyTracker.h"
+#include <vector>
+
#include "src/StatsLogProcessor.h"
+#include "src/StatsService.h"
+#include "src/anomaly/DurationAnomalyTracker.h"
#include "src/stats_log_util.h"
#include "tests/statsd_test_util.h"
-#include <vector>
+using ::ndk::SharedRefBase;
namespace android {
namespace os {
@@ -29,6 +34,9 @@ namespace statsd {
namespace {
+const int kConfigKey = 789130124;
+const int kCallingUid = 0;
+
StatsdConfig CreateStatsdConfig(int num_buckets,
uint64_t threshold_ns,
DurationMetric::AggregationType aggregationType,
@@ -89,6 +97,13 @@ MetricDimensionKey dimensionKey2(
(int32_t)0x02010101), Value((int32_t)222))}),
DEFAULT_DIMENSION_KEY);
+void sendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
+ string str;
+ config.SerializeToString(&str);
+ std::vector<uint8_t> configAsVec(str.begin(), str.end());
+ service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
+}
+
} // namespace
TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
@@ -98,16 +113,18 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
const uint64_t alert_id = config.alert(0).id();
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
+ shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+ sendConfig(service, config);
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+ auto processor = service->mProcessor;
ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+ int64_t bucketStartTimeNs = processor->mTimeBaseNs;
+ int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
+ int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
+
sp<AnomalyTracker> anomalyTracker =
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -158,12 +175,13 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
(uint32_t)alarmFiredTimestampSec0);
+ EXPECT_EQ(alarmFiredTimestampSec0,
+ processor->getAnomalyAlarmMonitor()->getRegisteredAlarmTimeSec());
// Anomaly alarm fired.
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(alarmFiredTimestampSec0));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onAnomalyAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
+ auto alarmTriggerEvent = CreateBatterySaverOnEvent(alarmFiredTimestampSec0 * NS_PER_SEC);
+ processor->OnLogEvent(alarmTriggerEvent.get(), alarmFiredTimestampSec0 * NS_PER_SEC);
+
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
@@ -179,39 +197,39 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire wakelock wl1.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11,
- attributionUids2, attributionTags2, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11, attributionUids2,
+ attributionTags2, "wl1");
processor->OnLogEvent(acquire_event.get());
const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
(uint64_t)alarmFiredTimestampSec1);
// Release wakelock wl1.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
+ int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10) / NS_PER_SEC + 1,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
+ auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
static_cast<uint32_t>(alarmFiredTimestampSec1));
ASSERT_EQ(0u, alarmSet.size());
// Acquire wakelock wl1 near the end of bucket #0.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 2,
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 2,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Release the event at early bucket #1.
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Anomaly detected when stopping the alarm. The refractory period does not change.
EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
@@ -236,17 +254,17 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
// Condition turns true.
screen_off_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
+ CreateScreenStateChangedEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
processor->OnLogEvent(screen_off_event.get());
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Condition turns to false.
- screen_on_event =
- CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1,
- android::view::DisplayStateEnum::DISPLAY_STATE_ON);
- processor->OnLogEvent(screen_on_event.get());
+ int64_t condition_false_time = bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1;
+ screen_on_event = CreateScreenStateChangedEvent(
+ condition_false_time, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
+ processor->OnLogEvent(screen_on_event.get(), condition_false_time);
// Condition turns to false. Cancelled the alarm.
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Detected one anomaly.
@@ -262,12 +280,11 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
+ release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
processor->OnLogEvent(release_event.get());
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC) / NS_PER_SEC,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
}
@@ -279,16 +296,18 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
const uint64_t alert_id = config.alert(0).id();
const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
+ shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+ sendConfig(service, config);
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+ auto processor = service->mProcessor;
ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+ int64_t bucketStartTimeNs = processor->mTimeBaseNs;
+ int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
+ int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
+
sp<AnomalyTracker> anomalyTracker =
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -298,96 +317,97 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
// Acquire wakelock "wc1" in bucket #0.
auto acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Release wakelock "wc1" in bucket #0.
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 1;
+ auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire wakelock "wc1" in bucket #1.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1,
- attributionUids2, attributionTags2, "wl1");
+ acquire_event =
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 1,
+ attributionUids2, attributionTags2, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 100,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 100;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire wakelock "wc2" in bucket #2.
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids3, attributionTags3, "wl2");
+ acquire_event =
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + 1,
+ attributionUids3, attributionTags3, "wl2");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2,
+ EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3,
anomalyTracker->getAlarmTimestampSec(dimensionKey2));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
// Release wakelock "wc2" in bucket #2.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
+ attributionTags3, "wl2");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- EXPECT_EQ(refractory_period_sec +
- (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC) / NS_PER_SEC,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
// Acquire wakelock "wc1" in bucket #2.
acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC,
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC,
attributionUids2, attributionTags2, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3 + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Release wakelock "wc1" in bucket #2.
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC,
- attributionUids2, attributionTags2, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3.5 * NS_PER_SEC;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
+ attributionTags2, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ(refractory_period_sec +
- (int64_t)(bucketStartTimeNs + 2 * bucketSizeNs + 2.5 * NS_PER_SEC) /
- NS_PER_SEC +
- 1,
+ EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 4,
- attributionUids3, attributionTags3, "wl2");
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 4,
+ attributionUids3, attributionTags3, "wl2");
processor->OnLogEvent(acquire_event.get());
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs - NS_PER_SEC + 5,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 5,
+ attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- EXPECT_EQ((bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 1,
+ EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
anomalyTracker->getAlarmTimestampSec(dimensionKey2));
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 2,
- attributionUids3, attributionTags3, "wl2");
- processor->OnLogEvent(release_event.get());
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 6 * bucketSizeNs + 6,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC + 2;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
+ attributionTags3, "wl2");
+ processor->OnLogEvent(release_event.get(), release_event_time);
+ release_event = CreateReleaseWakelockEvent(release_event_time + 4, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time + 4);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
// The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
- EXPECT_EQ(refractory_period_sec + (int64_t)(bucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC +
+ EXPECT_EQ(refractory_period_sec +
+ (int64_t)(roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC) /
+ NS_PER_SEC +
1,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
}
@@ -396,20 +416,22 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
const int num_buckets = 2;
const uint64_t threshold_ns = 3 * NS_PER_SEC;
auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
- int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
- int64_t bucketSizeNs =
- TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000;
-
const uint64_t alert_id = config.alert(0).id();
+ int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
- ConfigKey cfgKey;
- auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+ shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+ sendConfig(service, config);
+
+ auto processor = service->mProcessor;
ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+ int64_t bucketStartTimeNs = processor->mTimeBaseNs;
+ int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
+
sp<AnomalyTracker> anomalyTracker =
processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -418,81 +440,81 @@ TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
processor->OnLogEvent(screen_off_event.get());
// Acquire wakelock "wc1" in bucket #0.
- auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 100,
+ auto acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 100,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
+ EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Acquire the wakelock "wc1" again.
acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
+ CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
// The alarm does not change.
- EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
+ EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// Anomaly alarm fired late.
- const int64_t firedAlarmTimestampNs = bucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
- auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
- static_cast<uint32_t>(firedAlarmTimestampNs / NS_PER_SEC));
- ASSERT_EQ(1u, alarmSet.size());
- processor->onAnomalyAlarmFired(firedAlarmTimestampNs, alarmSet);
+ const int64_t firedAlarmTimestampNs = roundedBucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
+ auto alarmTriggerEvent = CreateBatterySaverOnEvent(firedAlarmTimestampNs);
+ processor->OnLogEvent(alarmTriggerEvent.get(), firedAlarmTimestampNs);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
+ acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs - 100,
attributionUids1, attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ int64_t release_event_time = bucketStartTimeNs + 2 * bucketSizeNs + 1;
+ auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
// Within the refractory period. No anomaly.
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
// A new wakelock, but still within refractory period.
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC, attributionUids1,
+ attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
- attributionUids1, attributionTags1, "wl1");
+ release_event =
+ CreateReleaseWakelockEvent(roundedBucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
+ attributionUids1, attributionTags1, "wl1");
// Still in the refractory period. No anomaly.
processor->OnLogEvent(release_event.get());
EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 5,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 5, attributionUids1,
+ attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
+ EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- release_event =
- CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 4,
- attributionUids1, attributionTags1, "wl1");
- processor->OnLogEvent(release_event.get());
+ release_event_time = roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 4;
+ release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
+ attributionTags1, "wl1");
+ processor->OnLogEvent(release_event.get(), release_event_time);
EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
- acquire_event =
- CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs - 3 * NS_PER_SEC - 3,
- attributionUids1, attributionTags1, "wl1");
+ acquire_event = CreateAcquireWakelockEvent(
+ roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 3, attributionUids1,
+ attributionTags1, "wl1");
processor->OnLogEvent(acquire_event.get());
- EXPECT_EQ((bucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC,
+ EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
anomalyTracker->getAlarmTimestampSec(dimensionKey1));
}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
index 71561c3c7023..39248730802f 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
@@ -49,7 +49,7 @@ public class UiAutomationShellWrapper {
}
try {
if (isSet) {
- am.setActivityController(new DummyActivityController(), true);
+ am.setActivityController(new NoOpActivityController(), true);
} else {
am.setActivityController(null, true);
}
@@ -80,9 +80,9 @@ public class UiAutomationShellWrapper {
}
/**
- * Dummy, no interference, activity controller.
+ * No-op, no interference, activity controller.
*/
- private class DummyActivityController extends IActivityController.Stub {
+ private class NoOpActivityController extends IActivityController.Stub {
@Override
public boolean activityStarting(Intent intent, String pkg) throws RemoteException {
/* do nothing and let activity proceed normally */
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
index d862e1c2babb..e6fb7aa76e58 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
@@ -45,7 +45,7 @@ import java.util.List;
public class UiAutomatorTestCase extends TestCase {
private static final String DISABLE_IME = "disable_ime";
- private static final String DUMMY_IME_PACKAGE = "com.android.testing.dummyime";
+ private static final String STUB_IME_PACKAGE = "com.android.testing.stubime";
private static final int NOT_A_SUBTYPE_ID = -1;
private UiDevice mUiDevice;
@@ -58,7 +58,7 @@ public class UiAutomatorTestCase extends TestCase {
super.setUp();
mShouldDisableIme = "true".equals(mParams.getString(DISABLE_IME));
if (mShouldDisableIme) {
- setDummyIme();
+ setStubIme();
}
}
@@ -128,7 +128,7 @@ public class UiAutomatorTestCase extends TestCase {
SystemClock.sleep(ms);
}
- private void setDummyIme() {
+ private void setStubIme() {
Context context = ActivityThread.currentApplication();
if (context == null) {
throw new RuntimeException("ActivityThread.currentApplication() is null.");
@@ -138,13 +138,13 @@ public class UiAutomatorTestCase extends TestCase {
List<InputMethodInfo> infos = im.getInputMethodList();
String id = null;
for (InputMethodInfo info : infos) {
- if (DUMMY_IME_PACKAGE.equals(info.getComponent().getPackageName())) {
+ if (STUB_IME_PACKAGE.equals(info.getComponent().getPackageName())) {
id = info.getId();
}
}
if (id == null) {
throw new RuntimeException(String.format(
- "Required testing fixture missing: IME package (%s)", DUMMY_IME_PACKAGE));
+ "Required testing fixture missing: IME package (%s)", STUB_IME_PACKAGE));
}
if (context.checkSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 35cf39f1b056..bc8db029e06d 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -183,7 +183,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
// This is to work around a bug in b/34736819. This needs to be removed once app team
// fixes their side.
- private AnimatorListenerAdapter mDummyListener = new AnimatorListenerAdapter() {
+ private AnimatorListenerAdapter mAnimationEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mNodeMap.get(animation) == null) {
@@ -1186,7 +1186,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
}
private void startAnimation() {
- addDummyListener();
+ addAnimationEndListener();
// Register animation callback
addAnimationCallback(0);
@@ -1243,15 +1243,15 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
// This is to work around the issue in b/34736819, as the old behavior in AnimatorSet had
// masked a real bug in play movies. TODO: remove this and below once the root cause is fixed.
- private void addDummyListener() {
+ private void addAnimationEndListener() {
for (int i = 1; i < mNodes.size(); i++) {
- mNodes.get(i).mAnimation.addListener(mDummyListener);
+ mNodes.get(i).mAnimation.addListener(mAnimationEndListener);
}
}
- private void removeDummyListener() {
+ private void removeAnimationEndListener() {
for (int i = 1; i < mNodes.size(); i++) {
- mNodes.get(i).mAnimation.removeListener(mDummyListener);
+ mNodes.get(i).mAnimation.removeListener(mAnimationEndListener);
}
}
@@ -1301,7 +1301,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
tmpListeners.get(i).onAnimationEnd(this, mReversing);
}
}
- removeDummyListener();
+ removeAnimationEndListener();
mSelfPulse = true;
mReversing = false;
}
@@ -1346,7 +1346,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
anim.mNodeMap = new ArrayMap<Animator, Node>();
anim.mNodes = new ArrayList<Node>(nodeCount);
anim.mEvents = new ArrayList<AnimationEvent>();
- anim.mDummyListener = new AnimatorListenerAdapter() {
+ anim.mAnimationEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (anim.mNodeMap.get(animation) == null) {
@@ -1369,7 +1369,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
final Node node = mNodes.get(n);
Node nodeClone = node.clone();
// Remove the old internal listener from the cloned child
- nodeClone.mAnimation.removeListener(mDummyListener);
+ nodeClone.mAnimation.removeListener(mAnimationEndListener);
clonesMap.put(node, nodeClone);
anim.mNodes.add(nodeClone);
anim.mNodeMap.put(nodeClone.mAnimation, nodeClone);
@@ -2087,7 +2087,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
* animation starts.
*/
public Builder after(long delay) {
- // setup dummy ValueAnimator just to run the clock
+ // setup a ValueAnimator just to run the clock
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(delay);
after(anim);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4a982dd1a411..2be92826cf38 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -35,6 +35,7 @@ import android.annotation.RequiresPermission;
import android.annotation.StyleRes;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.app.VoiceInteractor.Request;
import android.app.admin.DevicePolicyManager;
import android.app.assist.AssistContent;
@@ -726,6 +727,7 @@ import java.util.function.Consumer;
* upload, independent of whether the original activity is paused, stopped,
* or finished.
*/
+@UiContext
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index ef30cb46318c..9cf0d2a3a36a 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -448,7 +448,7 @@ public abstract class ActivityManagerInternal {
public abstract int broadcastIntent(Intent intent,
IIntentReceiver resultTo,
String[] requiredPermissions, boolean serialized,
- int userId, int[] appIdWhitelist);
+ int userId, int[] appIdAllowList);
/**
* Add uid to the ActivityManagerService PendingStartActivityUids list.
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 5e05506eb416..9833ed60fe46 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -24,6 +24,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.StyleRes;
+import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -101,6 +102,7 @@ public class Dialog implements DialogInterface, Window.Callback,
private final WindowManager mWindowManager;
@UnsupportedAppUsage
+ @UiContext
final Context mContext;
@UnsupportedAppUsage
final Window mWindow;
@@ -158,7 +160,7 @@ public class Dialog implements DialogInterface, Window.Callback,
* @param context the context in which the dialog should run
* @see android.R.styleable#Theme_dialogTheme
*/
- public Dialog(@NonNull Context context) {
+ public Dialog(@UiContext @NonNull Context context) {
this(context, 0, true);
}
@@ -177,11 +179,12 @@ public class Dialog implements DialogInterface, Window.Callback,
* @param themeResId a style resource describing the theme to use for the
* window, or {@code 0} to use the default dialog theme
*/
- public Dialog(@NonNull Context context, @StyleRes int themeResId) {
+ public Dialog(@UiContext @NonNull Context context, @StyleRes int themeResId) {
this(context, themeResId, true);
}
- Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
+ Dialog(@UiContext @NonNull Context context, @StyleRes int themeResId,
+ boolean createContextThemeWrapper) {
if (createContextThemeWrapper) {
if (themeResId == Resources.ID_NULL) {
final TypedValue outValue = new TypedValue();
@@ -222,7 +225,7 @@ public class Dialog implements DialogInterface, Window.Callback,
mCancelMessage = cancelCallback;
}
- protected Dialog(@NonNull Context context, boolean cancelable,
+ protected Dialog(@UiContext @NonNull Context context, boolean cancelable,
@Nullable OnCancelListener cancelListener) {
this(context);
mCancelable = cancelable;
@@ -234,7 +237,9 @@ public class Dialog implements DialogInterface, Window.Callback,
*
* @return Context The Context used by the Dialog.
*/
- public final @NonNull Context getContext() {
+ @UiContext
+ @NonNull
+ public final Context getContext() {
return mContext;
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c5d343d168ca..0a80ccc13487 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -26,6 +26,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -213,7 +214,6 @@ public class WallpaperManager {
private static final Object sSync = new Object[0];
@UnsupportedAppUsage
private static Globals sGlobals;
-
private final Context mContext;
private final boolean mWcgEnabled;
private final ColorManagementProxy mCmProxy;
@@ -539,7 +539,8 @@ public class WallpaperManager {
}
}
- /*package*/ WallpaperManager(IWallpaperManager service, Context context, Handler handler) {
+ /*package*/ WallpaperManager(IWallpaperManager service, @UiContext Context context,
+ Handler handler) {
mContext = context;
if (service != null) {
initGlobals(service, context.getMainLooper());
diff --git a/core/java/android/app/WindowContext.java b/core/java/android/app/WindowContext.java
index cb416c923c60..5f72bac89d7b 100644
--- a/core/java/android/app/WindowContext.java
+++ b/core/java/android/app/WindowContext.java
@@ -20,6 +20,7 @@ import static android.view.WindowManagerGlobal.ADD_TOO_MANY_TOKENS;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiContext;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Bundle;
@@ -42,6 +43,7 @@ import java.lang.ref.Reference;
* @see Context#createWindowContext(int, Bundle)
* @hide
*/
+@UiContext
public class WindowContext extends ContextWrapper {
private final WindowManagerImpl mWindowManager;
private final IWindowManager mWms;
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 20aa0647d261..a789169ade39 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -919,7 +919,7 @@ public abstract class BackupAgent extends ContextWrapper {
/**
* Only specialized platform agents should overload this entry point to support
- * restores to crazy non-app locations.
+ * restores to non-app locations.
* @hide
*/
protected void onRestoreFile(ParcelFileDescriptor data, long size,
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 8a6cc95319fb..1345e66a355a 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -109,7 +109,7 @@ public final class UsageStatsManager {
/**
- * The app is whitelisted for some reason and the bucket cannot be changed.
+ * The app is exempted for some reason and the bucket cannot be changed.
* {@hide}
*/
@SystemApi
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index fa3df1da5935..fd605604a8f1 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1033,6 +1033,18 @@ public final class BluetoothDevice implements Parcelable {
}
/**
+ * Returns the anonymized hardware address of this BluetoothDevice. The first three octets
+ * will be suppressed for anonymization.
+ * <p> For example, "XX:XX:XX:AA:BB:CC".
+ *
+ * @return Anonymized bluetooth hardware address as string
+ * @hide
+ */
+ public String getAnonymizedAddress() {
+ return "XX:XX:XX" + getAddress().substring(8);
+ }
+
+ /**
* Get the friendly Bluetooth name of the remote device.
*
* <p>The local adapter will automatically retrieve remote names when
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
index 2649fbee4246..cf9eeca0d739 100644
--- a/core/java/android/companion/BluetoothDeviceFilter.java
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -142,6 +142,16 @@ public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice
}
@Override
+ public String toString() {
+ return "BluetoothDeviceFilter{"
+ + "mNamePattern=" + mNamePattern
+ + ", mAddress='" + mAddress + '\''
+ + ", mServiceUuids=" + mServiceUuids
+ + ", mServiceUuidMasks=" + mServiceUuidMasks
+ + '}';
+ }
+
+ @Override
public int describeContents() {
return 0;
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 60ecf64dd0a9..33be50d34777 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1620,13 +1620,12 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
* Implementation when a caller has performed an insert on the content
* provider, but that call has been rejected for the operation given
* to {@link #setAppOps(int, int)}. The default implementation simply
- * returns a dummy URI that is the base URI with a 0 path element
- * appended.
+ * returns a URI that is the base URI with a 0 path element appended.
*/
public Uri rejectInsert(Uri uri, ContentValues values) {
// If not allowed, we need to return some reasonable URI. Maybe the
// content provider should be responsible for this, but for now we
- // will just return the base URI with a dummy '0' tagged on to it.
+ // will just return the base URI with a '0' tagged on to it.
// You shouldn't be able to read if you can't write, anyway, so it
// shouldn't matter much what is returned.
return uri.buildUpon().appendPath("0").build();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 33f32fb6b9fe..b5eb043d847c 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -726,7 +726,7 @@ public abstract class ContentResolver implements ContentInterface {
/**
* In addition to {@link #SYNC_EXEMPTION_PROMOTE_BUCKET}, we put the sync adapter app in the
- * temp whitelist for 10 minutes, so that even RARE apps can run syncs right away.
+ * temp allowlist for 10 minutes, so that even RARE apps can run syncs right away.
* @hide
*/
public static final int SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP = 2;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2385712a71d1..16cdf2334ad8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -21,6 +21,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.CheckResult;
import android.annotation.ColorInt;
import android.annotation.ColorRes;
+import android.annotation.DisplayContext;
import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -33,6 +34,7 @@ import android.annotation.StyleableRes;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.IApplicationThread;
@@ -3750,6 +3752,7 @@ public abstract class Context {
* @see #getSystemService(String)
* @see android.view.WindowManager
*/
+ @UiContext
public static final String WINDOW_SERVICE = "window";
/**
@@ -3760,6 +3763,7 @@ public abstract class Context {
* @see #getSystemService(String)
* @see android.view.LayoutInflater
*/
+ @UiContext
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
/**
@@ -3932,6 +3936,7 @@ public abstract class Context {
*
* @see #getSystemService(String)
*/
+ @UiContext
public static final String WALLPAPER_SERVICE = "wallpaper";
/**
@@ -5789,6 +5794,7 @@ public abstract class Context {
*
* @return A {@link Context} for the display.
*/
+ @DisplayContext
public abstract Context createDisplayContext(@NonNull Display display);
/**
@@ -5853,7 +5859,9 @@ public abstract class Context {
* the current number of window contexts without adding any view by
* {@link WindowManager#addView} <b>exceeds five</b>.
*/
- public @NonNull Context createWindowContext(@WindowType int type, @Nullable Bundle options) {
+ @UiContext
+ @NonNull
+ public Context createWindowContext(@WindowType int type, @Nullable Bundle options) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
index b72eb040ea92..8d0baa7f53a5 100644
--- a/core/java/android/content/SyncStatusInfo.java
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -273,7 +273,7 @@ public class SyncStatusInfo implements Parcelable {
totalStats.numSyncs - totalStats.numSourceLocal - totalStats.numSourcePoll
- totalStats.numSourceOther
- totalStats.numSourceUser;
- if (totalStats.numSourcePeriodic < 0) { // Sanity check.
+ if (totalStats.numSourcePeriodic < 0) { // Consistency check.
totalStats.numSourcePeriodic = 0;
}
} else {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 72246ee32186..200604801b97 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -917,7 +917,7 @@ public class PackageParser {
* Automatically detects if the package is a monolithic style (single APK
* file) or cluster style (directory of APKs).
* <p>
- * This performs sanity checking on cluster style packages, such as
+ * This performs checking on cluster style packages, such as
* requiring identical package name and version codes, a single base APK,
* and unique split names.
*
@@ -1038,7 +1038,7 @@ public class PackageParser {
* package is a monolithic style (single APK file) or cluster style
* (directory of APKs).
* <p>
- * This performs sanity checking on cluster style packages, such as
+ * This performs checking on cluster style packages, such as
* requiring identical package name and version codes, a single base APK,
* and unique split names.
* <p>
@@ -1072,7 +1072,7 @@ public class PackageParser {
/**
* Parse all APKs contained in the given directory, treating them as a
- * single package. This also performs sanity checking, such as requiring
+ * single package. This also performs checking, such as requiring
* identical package name and version codes, a single base APK, and unique
* split names.
* <p>
diff --git a/core/java/android/content/pm/dex/DexMetadataHelper.java b/core/java/android/content/pm/dex/DexMetadataHelper.java
index cdb1d221d177..982fce918366 100644
--- a/core/java/android/content/pm/dex/DexMetadataHelper.java
+++ b/core/java/android/content/pm/dex/DexMetadataHelper.java
@@ -147,7 +147,7 @@ public class DexMetadataHelper {
/**
* Validate that the given file is a dex metadata archive.
- * This is just a sanity validation that the file is a zip archive.
+ * This is just a validation that the file is a zip archive.
*
* @throws PackageParserException if the file is not a .dm file.
*/
@@ -173,7 +173,7 @@ public class DexMetadataHelper {
* (for any foo.dm there should be either a 'foo' of a 'foo.apk' file).
* If that's not the case it throws {@code IllegalStateException}.
*
- * This is used to perform a basic sanity check during adb install commands.
+ * This is used to perform a basic check during adb install commands.
* (The installer does not support stand alone .dm files)
*/
public static void validateDexPaths(String[] paths) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 9480d369065d..6407f9b3c1b8 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1871,7 +1871,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public boolean isOtherSeqNewer(Configuration other) {
if (other == null) {
- // Sanity check.
+ // Validation check.
return false;
}
if (other.seq == 0) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 7c4692c9e3af..0efd883e8b55 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -219,7 +219,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
* even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
* The denial of service problem only comes into play when the pattern length gets
* into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
- * are at most a few dozen bytes in length, paranoid application developers may
+ * are at most a few dozen bytes in length, cautious application developers may
* want to reduce this parameter to something in the range of a few hundred
* if they know that external users are able to generate arbitrary patterns.
*/
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c5a11abe1136..7250801eec81 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -32,6 +32,7 @@ import android.annotation.IntDef;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiContext;
import android.app.ActivityManager;
import android.app.Dialog;
import android.compat.annotation.UnsupportedAppUsage;
@@ -258,6 +259,7 @@ import java.util.Collections;
* @attr ref android.R.styleable#InputMethodService_imeExtractEnterAnimation
* @attr ref android.R.styleable#InputMethodService_imeExtractExitAnimation
*/
+@UiContext
public class InputMethodService extends AbstractInputMethodService {
static final String TAG = "InputMethodService";
static final boolean DEBUG = false;
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index bb8d4fe19aa2..3dce130f5d61 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -276,7 +276,7 @@ public class DropBoxManager {
}
/**
- * Create a dummy instance for testing. All methods will fail unless
+ * Create an instance for testing. All methods will fail unless
* overridden with an appropriate mock implementation. To obtain a
* functional instance, use {@link android.content.Context#getSystemService}.
*/
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 87e70431bd12..70c924a46c17 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1306,7 +1306,7 @@ public final class FileUtils {
/** {@hide} */
public static int translateModeStringToPosix(String mode) {
- // Sanity check for invalid chars
+ // Quick check for invalid chars
for (int i = 0; i < mode.length(); i++) {
switch (mode.charAt(i)) {
case 'r':
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 1539b6ed4ca7..a6b869d19867 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -570,7 +570,7 @@ public class GraphicsEnvironment {
final ContentResolver contentResolver = context.getContentResolver();
final List<String> angleAllowlist =
getGlobalSettingsString(contentResolver, bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
+ Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST);
if (DEBUG) Log.v(TAG, "ANGLE allowlist: " + angleAllowlist);
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 0ec4fb832801..40c291f14b67 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -16,6 +16,6 @@ per-file PowerManager.java = michaelwr@google.com, santoscordon@google.com
per-file PowerManagerInternal.java = michaelwr@google.com, santoscordon@google.com
# Zygote
-per-file ZygoteProcess.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+per-file ZygoteProcess.java = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING
index f4645caee511..39c196d1a06c 100644
--- a/core/java/android/os/TEST_MAPPING
+++ b/core/java/android/os/TEST_MAPPING
@@ -1,6 +1,14 @@
{
"presubmit": [
- // TODO(159590499) add BugreportManagerTestCases
+ {
+ "file_patterns": ["Bugreport[^/]*\\.java"],
+ "name": "BugreportManagerTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ },
{
"file_patterns": ["Bugreport[^/]*\\.java"],
"name": "CtsBugreportTestCases",
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 39038f555044..ffede09f99d6 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -251,11 +251,11 @@ public class ZygoteProcess {
private final Object mLock = new Object();
/**
- * List of exemptions to the API blacklist. These are prefix matches on the runtime format
+ * List of exemptions to the API deny list. These are prefix matches on the runtime format
* symbol signature. Any matching symbol is treated by the runtime as being on the light grey
* list.
*/
- private List<String> mApiBlacklistExemptions = Collections.emptyList();
+ private List<String> mApiDenylistExemptions = Collections.emptyList();
/**
* Proportion of hidden API accesses that should be logged to the event log; 0 - 0x10000.
@@ -562,7 +562,7 @@ public class ZygoteProcess {
"--preload-package",
"--preload-app",
"--start-child-zygote",
- "--set-api-blacklist-exemptions",
+ "--set-api-denylist-exemptions",
"--hidden-api-log-sampling-rate",
"--hidden-api-statslog-sampling-rate",
"--invoke-with"
@@ -922,20 +922,20 @@ public class ZygoteProcess {
}
/**
- * Push hidden API blacklisting exemptions into the zygote process(es).
+ * Push hidden API deny-listing exemptions into the zygote process(es).
*
* <p>The list of exemptions will take affect for all new processes forked from the zygote after
* this call.
*
* @param exemptions List of hidden API exemption prefixes. Any matching members are treated as
- * whitelisted/public APIs (i.e. allowed, no logging of usage).
+ * allowed/public APIs (i.e. allowed, no logging of usage).
*/
- public boolean setApiBlacklistExemptions(List<String> exemptions) {
+ public boolean setApiDenylistExemptions(List<String> exemptions) {
synchronized (mLock) {
- mApiBlacklistExemptions = exemptions;
- boolean ok = maybeSetApiBlacklistExemptions(primaryZygoteState, true);
+ mApiDenylistExemptions = exemptions;
+ boolean ok = maybeSetApiDenylistExemptions(primaryZygoteState, true);
if (ok) {
- ok = maybeSetApiBlacklistExemptions(secondaryZygoteState, true);
+ ok = maybeSetApiDenylistExemptions(secondaryZygoteState, true);
}
return ok;
}
@@ -972,32 +972,32 @@ public class ZygoteProcess {
}
@GuardedBy("mLock")
- private boolean maybeSetApiBlacklistExemptions(ZygoteState state, boolean sendIfEmpty) {
+ private boolean maybeSetApiDenylistExemptions(ZygoteState state, boolean sendIfEmpty) {
if (state == null || state.isClosed()) {
- Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection");
+ Slog.e(LOG_TAG, "Can't set API denylist exemptions: no zygote connection");
return false;
- } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
+ } else if (!sendIfEmpty && mApiDenylistExemptions.isEmpty()) {
return true;
}
try {
- state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1));
+ state.mZygoteOutputWriter.write(Integer.toString(mApiDenylistExemptions.size() + 1));
state.mZygoteOutputWriter.newLine();
- state.mZygoteOutputWriter.write("--set-api-blacklist-exemptions");
+ state.mZygoteOutputWriter.write("--set-api-denylist-exemptions");
state.mZygoteOutputWriter.newLine();
- for (int i = 0; i < mApiBlacklistExemptions.size(); ++i) {
- state.mZygoteOutputWriter.write(mApiBlacklistExemptions.get(i));
+ for (int i = 0; i < mApiDenylistExemptions.size(); ++i) {
+ state.mZygoteOutputWriter.write(mApiDenylistExemptions.get(i));
state.mZygoteOutputWriter.newLine();
}
state.mZygoteOutputWriter.flush();
int status = state.mZygoteInputStream.readInt();
if (status != 0) {
- Slog.e(LOG_TAG, "Failed to set API blacklist exemptions; status " + status);
+ Slog.e(LOG_TAG, "Failed to set API denylist exemptions; status " + status);
}
return true;
} catch (IOException ioe) {
- Slog.e(LOG_TAG, "Failed to set API blacklist exemptions", ioe);
- mApiBlacklistExemptions = Collections.emptyList();
+ Slog.e(LOG_TAG, "Failed to set API denylist exemptions", ioe);
+ mApiDenylistExemptions = Collections.emptyList();
return false;
}
}
@@ -1054,7 +1054,7 @@ public class ZygoteProcess {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
- maybeSetApiBlacklistExemptions(primaryZygoteState, false);
+ maybeSetApiDenylistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
}
@@ -1069,7 +1069,7 @@ public class ZygoteProcess {
ZygoteState.connect(mZygoteSecondarySocketAddress,
mUsapPoolSecondarySocketAddress);
- maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
+ maybeSetApiDenylistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bd7e610b6b9e..5acc11a868bf 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8728,16 +8728,6 @@ public final class Settings {
= "bubble_important_conversations";
/**
- * When enabled, notifications the notification assistant service has modified will show an
- * indicator. When tapped, this indicator will describe the adjustment made and solicit
- * feedback. This flag will also add a "automatic" option to the long press menu.
- *
- * The value 1 - enable, 0 - disable
- * @hide
- */
- public static final String NOTIFICATION_FEEDBACK_ENABLED = "notification_feedback_enabled";
-
- /**
* Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right
* swipe).
*
@@ -10855,17 +10845,6 @@ public final class Settings {
public static final String MODE_RINGER = "mode_ringer";
/**
- * Specifies whether Enhanced Connectivity is enabled or not. This setting allows the
- * Connectivity Thermal Power Manager to actively help the device to save power in 5G
- * scenarios
- * Type: int 1 is enabled, 0 is disabled
- *
- * @hide
- */
- public static final String ENHANCED_CONNECTIVITY_ENABLED =
- "enhanced_connectivity_enable";
-
- /**
* Overlay display devices setting.
* The associated value is a specially formatted string that describes the
* size and density of simulated secondary display devices.
@@ -12349,8 +12328,8 @@ public final class Settings {
* List of package names that should check ANGLE rules
* @hide
*/
- public static final String GLOBAL_SETTINGS_ANGLE_WHITELIST =
- "angle_whitelist";
+ public static final String GLOBAL_SETTINGS_ANGLE_ALLOWLIST =
+ "angle_allowlist";
/**
* Show the "ANGLE In Use" dialog box to the user when ANGLE is the OpenGL driver.
@@ -14058,6 +14037,16 @@ public final class Settings {
"notification_snooze_options";
/**
+ * When enabled, notifications the notification assistant service has modified will show an
+ * indicator. When tapped, this indicator will describe the adjustment made and solicit
+ * feedback. This flag will also add a "automatic" option to the long press menu.
+ *
+ * The value 1 - enable, 0 - disable
+ * @hide
+ */
+ public static final String NOTIFICATION_FEEDBACK_ENABLED = "notification_feedback_enabled";
+
+ /**
* Settings key for the ratio of notification dismissals to notification views - one of the
* criteria for showing the notification blocking helper.
*
diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java
index 8be114ca321e..2cd8b8ba42d9 100644
--- a/core/java/android/service/notification/NotificationStats.java
+++ b/core/java/android/service/notification/NotificationStats.java
@@ -73,6 +73,11 @@ public final class NotificationStats implements Parcelable {
* Notification has been dismissed from the notification shade.
*/
public static final int DISMISSAL_SHADE = 3;
+ /**
+ * Notification has been dismissed as a bubble.
+ * @hide
+ */
+ public static final int DISMISSAL_BUBBLE = 3;
/** @hide */
@IntDef(prefix = { "DISMISS_SENTIMENT_" }, value = {
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 0a47032354f5..a720601d81ff 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -26,10 +26,8 @@ import android.os.Binder;
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType;
-import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DisconnectCauses;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.PreciseCallStates;
@@ -37,7 +35,6 @@ import android.telephony.Annotation.PreciseDisconnectCauses;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
-import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
import android.util.Log;
@@ -402,17 +399,16 @@ public class TelephonyRegistryManager {
* @param subId for which data connection state changed.
* @param slotIndex for which data connections state changed. Can be derived from subId except
* when subId is invalid.
- * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags.
* @param preciseState the PreciseDataConnectionState
*
- * @see android.telephony.PreciseDataConnection
+ * @see PreciseDataConnectionState
* @see TelephonyManager#DATA_DISCONNECTED
*/
public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
- @ApnType int apnType, @Nullable PreciseDataConnectionState preciseState) {
+ @NonNull PreciseDataConnectionState preciseState) {
try {
sRegistry.notifyDataConnectionForSubscriber(
- slotIndex, subId, apnType, preciseState);
+ slotIndex, subId, preciseState);
} catch (RemoteException ex) {
// system process is dead
}
@@ -612,25 +608,6 @@ public class TelephonyRegistryManager {
}
/**
- * Notify precise data connection failed cause on certain subscription.
- *
- * @param subId for which data connection failed.
- * @param slotIndex for which data conenction failed. Can be derived from subId except when
- * subId is invalid.
- * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags.
- * @param apn the APN {@link ApnSetting#getApnName()} of this data connection.
- * @param failCause data fail cause.
- */
- public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, @ApnType int apnType,
- @Nullable String apn, @DataFailureCause int failCause) {
- try {
- sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- /**
* Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call
* on certain subscription.
*
diff --git a/core/java/android/util/proto/ProtoInputStream.java b/core/java/android/util/proto/ProtoInputStream.java
index cbe3734ce5fa..aa70d07ff787 100644
--- a/core/java/android/util/proto/ProtoInputStream.java
+++ b/core/java/android/util/proto/ProtoInputStream.java
@@ -96,7 +96,7 @@ public final class ProtoInputStream extends ProtoStream {
private byte mState = 0;
/**
- * Keeps track of the currently read nested Objects, for end object sanity checking and debug
+ * Keeps track of the currently read nested Objects, for end object checking and debug
*/
private ArrayList<Long> mExpectedObjectTokenStack = null;
@@ -513,7 +513,7 @@ public final class ProtoInputStream extends ProtoStream {
(int) fieldId, getOffset() + messageSize));
}
- // Sanity check
+ // Validation check
if (mDepth > 0
&& getOffsetFromToken(mExpectedObjectTokenStack.get(mDepth))
> getOffsetFromToken(mExpectedObjectTokenStack.get(mDepth - 1))) {
@@ -536,7 +536,7 @@ public final class ProtoInputStream extends ProtoStream {
* @param token - token
*/
public void end(long token) {
- // Sanity check to make sure user is keeping track of their embedded messages
+ // Make sure user is keeping track of their embedded messages
if (mExpectedObjectTokenStack.get(mDepth) != token) {
throw new ProtoParseException(
"end token " + token + " does not match current message token "
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index 5fcd38e2fd9c..afca4ab2c741 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -59,10 +59,10 @@ import java.io.UnsupportedEncodingException;
* cache the size, and then write the size-prefixed buffers.
*
* We are trying to avoid too much generated code here, but this class still
- * needs to have a somewhat sane API. We can't have the multiple passes be
- * done by the calling code. In addition, we want to avoid the memory high
- * water mark of duplicating all of the values into the traditional in-memory
- * Message objects. We need to find another way.
+ * needs to have API. We can't have the multiple passes be done by the
+ * calling code. In addition, we want to avoid the memory high water mark
+ * of duplicating all of the values into the traditional in-memory Message
+ * objects. We need to find another way.
*
* So what we do here is to let the calling code write the data into a
* byte[] (actually a collection of them wrapped in the EncodedBuffer class),
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 713cfb48c95f..064bc6947fc4 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -311,6 +311,9 @@ public class FocusFinder {
}
final int count = focusables.size();
+ if (count < 2) {
+ return null;
+ }
switch (direction) {
case View.FOCUS_FORWARD:
return getNextFocusable(focused, focusables, count);
@@ -373,29 +376,29 @@ public class FocusFinder {
}
private static View getNextFocusable(View focused, ArrayList<View> focusables, int count) {
+ if (count < 2) {
+ return null;
+ }
if (focused != null) {
int position = focusables.lastIndexOf(focused);
if (position >= 0 && position + 1 < count) {
return focusables.get(position + 1);
}
}
- if (!focusables.isEmpty()) {
- return focusables.get(0);
- }
- return null;
+ return focusables.get(0);
}
private static View getPreviousFocusable(View focused, ArrayList<View> focusables, int count) {
+ if (count < 2) {
+ return null;
+ }
if (focused != null) {
int position = focusables.indexOf(focused);
if (position > 0) {
return focusables.get(position - 1);
}
}
- if (!focusables.isEmpty()) {
- return focusables.get(count - 1);
- }
- return null;
+ return focusables.get(count - 1);
}
private static View getNextKeyboardNavigationCluster(
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 55c527ba6fa6..8a722184eb77 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -25,6 +25,7 @@ import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFI
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
+import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
@@ -393,7 +394,7 @@ public class GestureDetector {
*
* @throws NullPointerException if {@code listener} is null.
*/
- public GestureDetector(Context context, OnGestureListener listener) {
+ public GestureDetector(@UiContext Context context, OnGestureListener listener) {
this(context, listener, null);
}
@@ -412,7 +413,8 @@ public class GestureDetector {
*
* @throws NullPointerException if {@code listener} is null.
*/
- public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
+ public GestureDetector(@UiContext Context context, OnGestureListener listener,
+ Handler handler) {
if (handler != null) {
mHandler = new GestureHandler(handler);
} else {
@@ -442,12 +444,12 @@ public class GestureDetector {
*
* @throws NullPointerException if {@code listener} is null.
*/
- public GestureDetector(Context context, OnGestureListener listener, Handler handler,
+ public GestureDetector(@UiContext Context context, OnGestureListener listener, Handler handler,
boolean unused) {
this(context, listener, handler);
}
- private void init(Context context) {
+ private void init(@UiContext Context context) {
if (mListener == null) {
throw new NullPointerException("OnGestureListener must not be null");
}
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 1afe11ea1acf..b925b492c04b 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -94,6 +95,7 @@ public abstract class LayoutInflater {
* {@hide}
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @UiContext
protected final Context mContext;
// these are optional, set by the caller
@@ -277,7 +279,7 @@ public abstract class LayoutInflater {
/**
* Obtains the LayoutInflater from the given context.
*/
- public static LayoutInflater from(Context context) {
+ public static LayoutInflater from(@UiContext Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ecf97749d349..8cb8e1d12d8a 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -22,6 +22,7 @@ import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo.Translator;
import android.graphics.Canvas;
import android.graphics.ColorSpace;
@@ -1001,7 +1002,10 @@ public class Surface implements Parcelable {
mHardwareRenderer = new HardwareRenderer();
mHardwareRenderer.setContentRoot(mRenderNode);
mHardwareRenderer.setSurface(Surface.this, true);
- mHardwareRenderer.setWideGamut(isWideColorGamut);
+ mHardwareRenderer.setColorMode(
+ isWideColorGamut
+ ? ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT
+ : ActivityInfo.COLOR_MODE_DEFAULT);
mHardwareRenderer.setLightSourceAlpha(0.0f, 0.0f);
mHardwareRenderer.setLightSourceGeometry(0.0f, 0.0f, 0.0f, 0.0f);
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6beea8764ed1..50ed00cd0aa7 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -89,13 +89,10 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeWriteToParcel(long nativeObject, Parcel out);
private static native void nativeRelease(long nativeObject);
private static native void nativeDisconnect(long nativeObject);
-
- private static native ScreenshotHardwareBuffer nativeScreenshot(IBinder displayToken,
- Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
- boolean captureSecureLayers);
- private static native ScreenshotHardwareBuffer nativeCaptureLayers(IBinder displayToken,
- long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects,
- int format);
+ private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
+ DisplayCaptureArgs captureArgs);
+ private static native ScreenshotHardwareBuffer nativeCaptureLayers(
+ LayerCaptureArgs captureArgs);
private static native long nativeMirrorSurface(long mirrorOfObject);
private static native long nativeCreateTransaction();
private static native long nativeGetNativeTransactionFinalizer();
@@ -572,7 +569,8 @@ public final class SurfaceControl implements Parcelable {
* Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
* @param hardwareBuffer The existing HardwareBuffer object
* @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
- * @param containsSecureLayer Indicates whether this graphic buffer contains captured contents
+ * @param containsSecureLayers Indicates whether this graphic buffer contains captured
+ * contents
* of secure layers, in which case the screenshot should not be persisted.
*/
private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
@@ -595,6 +593,260 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * A common arguments class used for various screenshot requests. This contains arguments that
+ * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs}
+ * @hide
+ */
+ public abstract static class CaptureArgs {
+ private final int mPixelFormat;
+ private final Rect mSourceCrop = new Rect();
+ private final float mFrameScale;
+ private final boolean mCaptureSecureLayers;
+
+ private CaptureArgs(Builder<? extends Builder<?>> builder) {
+ mPixelFormat = builder.mPixelFormat;
+ mSourceCrop.set(builder.mSourceCrop);
+ mFrameScale = builder.mFrameScale;
+ mCaptureSecureLayers = builder.mCaptureSecureLayers;
+ }
+
+ /**
+ * The Builder class used to construct {@link CaptureArgs}
+ *
+ * @param <T> A builder that extends {@link Builder}
+ */
+ public abstract static class Builder<T extends Builder<T>> {
+ private int mPixelFormat = PixelFormat.RGBA_8888;
+ private final Rect mSourceCrop = new Rect();
+ private float mFrameScale = 1;
+ private boolean mCaptureSecureLayers;
+
+ /**
+ * The desired pixel format of the returned buffer.
+ */
+ public T setPixelFormat(int pixelFormat) {
+ mPixelFormat = pixelFormat;
+ return getThis();
+ }
+
+ /**
+ * The portion of the screen to capture into the buffer. Caller may pass in
+ * 'new Rect()' if no cropping is desired.
+ */
+ public T setSourceCrop(Rect sourceCrop) {
+ mSourceCrop.set(sourceCrop);
+ return getThis();
+ }
+
+ /**
+ * The desired scale of the returned buffer. The raw screen will be scaled up/down.
+ */
+ public T setFrameScale(float frameScale) {
+ mFrameScale = frameScale;
+ return getThis();
+ }
+
+ /**
+ * Whether to allow the screenshot of secure layers. Warning: This should only be done
+ * if the content will be placed in a secure SurfaceControl.
+ *
+ * @see ScreenshotHardwareBuffer#containsSecureLayers()
+ */
+ public T setCaptureSecureLayers(boolean captureSecureLayers) {
+ mCaptureSecureLayers = captureSecureLayers;
+ return getThis();
+ }
+
+ /**
+ * Each sub class should return itself to allow the builder to chain properly
+ */
+ abstract T getThis();
+ }
+ }
+
+ /**
+ * The arguments class used to make display capture requests.
+ *
+ * @see #nativeCaptureDisplay(DisplayCaptureArgs)
+ * @hide
+ */
+ public static class DisplayCaptureArgs extends CaptureArgs {
+ private final IBinder mDisplayToken;
+ private final int mWidth;
+ private final int mHeight;
+ private final boolean mUseIdentityTransform;
+ private final int mRotation;
+
+ private DisplayCaptureArgs(Builder builder) {
+ super(builder);
+ mDisplayToken = builder.mDisplayToken;
+ mWidth = builder.mWidth;
+ mHeight = builder.mHeight;
+ mUseIdentityTransform = builder.mUseIdentityTransform;
+ mRotation = builder.mRotation;
+ }
+
+ /**
+ * The Builder class used to construct {@link DisplayCaptureArgs}
+ */
+ public static class Builder extends CaptureArgs.Builder<Builder> {
+ private IBinder mDisplayToken;
+ private int mWidth;
+ private int mHeight;
+ private boolean mUseIdentityTransform;
+ private @Surface.Rotation int mRotation = Surface.ROTATION_0;
+
+ /**
+ * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder
+ * remains valid.
+ */
+ public DisplayCaptureArgs build() {
+ if (mDisplayToken == null) {
+ throw new IllegalStateException(
+ "Can't take screenshot with null display token");
+ }
+ return new DisplayCaptureArgs(this);
+ }
+
+ public Builder(IBinder displayToken) {
+ setDisplayToken(displayToken);
+ }
+
+ /**
+ * The display to take the screenshot of.
+ */
+ public Builder setDisplayToken(IBinder displayToken) {
+ mDisplayToken = displayToken;
+ return this;
+ }
+
+ /**
+ * Set the desired size of the returned buffer. The raw screen will be scaled down to
+ * this size
+ *
+ * @param width The desired width of the returned buffer. Caller may pass in 0 if no
+ * scaling is desired.
+ * @param height The desired height of the returned buffer. Caller may pass in 0 if no
+ * scaling is desired.
+ */
+ public Builder setSize(int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ return this;
+ }
+
+ /**
+ * Replace whatever transformation (rotation, scaling, translation) the surface
+ * layers are currently using with the identity transformation while taking the
+ * screenshot.
+ */
+ public Builder setUseIdentityTransform(boolean useIdentityTransform) {
+ mUseIdentityTransform = useIdentityTransform;
+ return this;
+ }
+
+ /**
+ * Apply a custom clockwise rotation to the screenshot, i.e.
+ * Surface.ROTATION_0,90,180,270. SurfaceFlinger will always take screenshots in its
+ * native portrait orientation by default, so this is useful for returning screenshots
+ * that are independent of device orientation.
+ */
+ public Builder setRotation(@Surface.Rotation int rotation) {
+ mRotation = rotation;
+ return this;
+ }
+
+ @Override
+ Builder getThis() {
+ return this;
+ }
+ }
+ }
+
+ /**
+ * The arguments class used to make layer capture requests.
+ *
+ * @see #nativeCaptureLayers(LayerCaptureArgs)
+ * @hide
+ */
+ public static class LayerCaptureArgs extends CaptureArgs {
+ private final long mNativeLayer;
+ private final long[] mNativeExcludeLayers;
+ private final boolean mChildrenOnly;
+
+ private LayerCaptureArgs(Builder builder) {
+ super(builder);
+ mChildrenOnly = builder.mChildrenOnly;
+ mNativeLayer = builder.mLayer.mNativeObject;
+ if (builder.mExcludeLayers != null) {
+ mNativeExcludeLayers = new long[builder.mExcludeLayers.length];
+ for (int i = 0; i < builder.mExcludeLayers.length; i++) {
+ mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject;
+ }
+ } else {
+ mNativeExcludeLayers = null;
+ }
+ }
+
+ /**
+ * The Builder class used to construct {@link LayerCaptureArgs}
+ */
+ public static class Builder extends CaptureArgs.Builder<Builder> {
+ private SurfaceControl mLayer;
+ private SurfaceControl[] mExcludeLayers;
+ private boolean mChildrenOnly = true;
+
+ /**
+ * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder
+ * remains valid.
+ */
+ public LayerCaptureArgs build() {
+ if (mLayer == null) {
+ throw new IllegalStateException(
+ "Can't take screenshot with null layer");
+ }
+ return new LayerCaptureArgs(this);
+ }
+
+ public Builder(SurfaceControl layer) {
+ setLayer(layer);
+ }
+
+ /**
+ * The root layer to capture.
+ */
+ public Builder setLayer(SurfaceControl layer) {
+ mLayer = layer;
+ return this;
+ }
+
+
+ /**
+ * An array of layer handles to exclude.
+ */
+ public Builder setExcludeLayers(@Nullable SurfaceControl[] excludeLayers) {
+ mExcludeLayers = excludeLayers;
+ return this;
+ }
+
+ /**
+ * Whether to include the layer itself in the screenshot or just the children and their
+ * descendants.
+ */
+ public Builder setChildrenOnly(boolean childrenOnly) {
+ mChildrenOnly = childrenOnly;
+ return this;
+ }
+
+ @Override
+ Builder getThis() {
+ return this;
+ }
+
+ }
+ }
+
+ /**
* Builder class for {@link SurfaceControl} objects.
*
* By default the surface will be hidden, and have "unset" bounds, meaning it can
@@ -1969,37 +2221,6 @@ public final class SurfaceControl implements Parcelable {
}
/**
- * @see SurfaceControl#screenshot(IBinder, Surface, Rect, int, int, boolean, int)
- * @hide
- */
- public static void screenshot(IBinder display, Surface consumer) {
- screenshot(display, consumer, new Rect(), 0, 0, false, 0);
- }
-
- /**
- * Copy the current screen contents into the provided {@link Surface}
- *
- * @param consumer The {@link Surface} to take the screenshot into.
- * @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)
- * @hide
- */
- public static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width,
- int height, boolean useIdentityTransform, int rotation) {
- if (consumer == null) {
- throw new IllegalArgumentException("consumer must not be null");
- }
-
- final ScreenshotHardwareBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
- height, useIdentityTransform, rotation);
- try {
- consumer.attachAndQueueBufferWithColorSpace(buffer.getHardwareBuffer(),
- buffer.getColorSpace());
- } catch (RuntimeException e) {
- Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
- }
- }
-
- /**
* @see SurfaceControl#screenshot(Rect, int, int, boolean, int)}
* @hide
*/
@@ -2014,8 +2235,7 @@ public final class SurfaceControl implements Parcelable {
* a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)}
*
* CAVEAT: Versions of screenshot that return a {@link Bitmap} can be extremely slow; avoid use
- * unless absolutely necessary; prefer the versions that use a {@link Surface} such as
- * {@link SurfaceControl#screenshot(IBinder, Surface)} or {@link HardwareBuffer} such as
+ * unless absolutely necessary; prefer the versions that use a {@link HardwareBuffer} such as
* {@link SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}.
*
* @see SurfaceControl#screenshotToBuffer(IBinder, Rect, int, int, boolean, int)}
@@ -2075,8 +2295,14 @@ public final class SurfaceControl implements Parcelable {
throw new IllegalArgumentException("displayToken must not be null");
}
- return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
- false /* captureSecureLayers */);
+ DisplayCaptureArgs captureArgs = new DisplayCaptureArgs.Builder(display)
+ .setSourceCrop(sourceCrop)
+ .setSize(width, height)
+ .setUseIdentityTransform(useIdentityTransform)
+ .setRotation(rotation)
+ .build();
+
+ return nativeCaptureDisplay(captureArgs);
}
/**
@@ -2096,8 +2322,15 @@ public final class SurfaceControl implements Parcelable {
throw new IllegalArgumentException("displayToken must not be null");
}
- return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
- true /* captureSecureLayers */);
+ DisplayCaptureArgs captureArgs = new DisplayCaptureArgs.Builder(display)
+ .setSourceCrop(sourceCrop)
+ .setSize(width, height)
+ .setUseIdentityTransform(useIdentityTransform)
+ .setRotation(rotation)
+ .setCaptureSecureLayers(true)
+ .build();
+
+ return nativeCaptureDisplay(captureArgs);
}
private static void rotateCropForSF(Rect crop, int rot) {
@@ -2147,24 +2380,30 @@ public final class SurfaceControl implements Parcelable {
*/
public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
float frameScale, int format) {
- final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
- return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null,
- format);
+ LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
+ .setSourceCrop(sourceCrop)
+ .setFrameScale(frameScale)
+ .setPixelFormat(format)
+ .build();
+
+ return nativeCaptureLayers(captureArgs);
}
/**
- * Like {@link captureLayers} but with an array of layer handles to exclude.
+ * Like {@link #captureLayers(SurfaceControl, Rect, float, int)} but with an array of layer
+ * handles to exclude.
* @hide
*/
public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer,
Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
- final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
- long[] nativeExcludeObjects = new long[exclude.length];
- for (int i = 0; i < exclude.length; i++) {
- nativeExcludeObjects[i] = exclude[i].mNativeObject;
- }
- return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale,
- nativeExcludeObjects, PixelFormat.RGBA_8888);
+ LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
+ .setSourceCrop(sourceCrop)
+ .setFrameScale(frameScale)
+ .setPixelFormat(format)
+ .setExcludeLayers(exclude)
+ .build();
+
+ return nativeCaptureLayers(captureArgs);
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e951156ec4cc..0818abeff923 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -43,6 +43,7 @@ import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.StyleRes;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.annotation.UiThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AutofillOptions;
@@ -952,8 +953,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Prior to P, {@code #startDragAndDrop} accepts a builder which produces an empty drag shadow.
- * Currently zero size SurfaceControl cannot be created thus we create a dummy 1x1 surface
- * instead.
+ * Currently zero size SurfaceControl cannot be created thus we create a 1x1 surface instead.
*/
private static boolean sAcceptZeroSizeDragShadow;
@@ -4910,6 +4910,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty(deepExport = true)
@UnsupportedAppUsage
+ @UiContext
protected Context mContext;
@UnsupportedAppUsage
@@ -15071,6 +15072,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return The view's Context.
*/
@ViewDebug.CapturedViewProperty
+ @UiContext
public final Context getContext() {
return mContext;
}
@@ -30023,7 +30025,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Dump all private flags in readable format, useful for documentation and
- * sanity checking.
+ * consistency checking.
*/
private static void dumpFlags() {
final HashMap<String, String> found = Maps.newHashMap();
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index ffeeb806ba54..ccf1fb07d0bb 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -20,6 +20,7 @@ import static android.os.StrictMode.vmIncorrectContextUseEnabled;
import android.annotation.FloatRange;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.app.Activity;
import android.app.AppGlobals;
import android.compat.annotation.UnsupportedAppUsage;
@@ -391,7 +392,7 @@ public class ViewConfiguration {
* @see #get(android.content.Context)
* @see android.util.DisplayMetrics
*/
- private ViewConfiguration(Context context) {
+ private ViewConfiguration(@UiContext Context context) {
mConstructedWithContext = true;
final Resources res = context.getResources();
final DisplayMetrics metrics = res.getDisplayMetrics();
@@ -498,7 +499,8 @@ public class ViewConfiguration {
* be {@link Activity} or other {@link Context} created with
* {@link Context#createWindowContext(int, Bundle)}.
*/
- public static ViewConfiguration get(Context context) {
+
+ public static ViewConfiguration get(@UiContext Context context) {
if (!context.isUiContext() && vmIncorrectContextUseEnabled()) {
final String errorMessage = "Tried to access UI constants from a non-visual Context:"
+ context;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6552e30dde69..64ddb2f4d9d9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -64,6 +64,7 @@ import android.animation.LayoutTransition;
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiContext;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ResourcesManager;
@@ -349,6 +350,7 @@ public final class ViewRootImpl implements ViewParent,
@GuardedBy("mWindowCallbacks")
final ArrayList<WindowCallbacks> mWindowCallbacks = new ArrayList<>();
@UnsupportedAppUsage
+ @UiContext
public final Context mContext;
@UnsupportedAppUsage
@@ -719,11 +721,11 @@ public final class ViewRootImpl implements ViewParent,
false /* useSfChoreographer */);
}
- public ViewRootImpl(Context context, Display display, IWindowSession session) {
+ public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) {
this(context, display, session, false /* useSfChoreographer */);
}
- public ViewRootImpl(Context context, Display display, IWindowSession session,
+ public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
boolean useSfChoreographer) {
mContext = context;
mWindowSession = session;
@@ -1329,13 +1331,9 @@ public final class ViewRootImpl implements ViewParent,
final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
|| insets.top != 0 || insets.bottom != 0;
final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
- final boolean wideGamut =
- mContext.getResources().getConfiguration().isScreenWideColorGamut()
- && attrs.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
-
mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
attrs.getTitle().toString());
- mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
+ updateColorModeIfNeeded(attrs.getColorMode());
updateForceDarkMode();
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mHardwareAccelerated =
@@ -2648,7 +2646,7 @@ public final class ViewRootImpl implements ViewParent,
& WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
final boolean alwaysConsumeSystemBarsChanged =
mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars;
- final boolean colorModeChanged = hasColorModeChanged(lp.getColorMode());
+ updateColorModeIfNeeded(lp.getColorMode());
surfaceCreated = !hadSurface && mSurface.isValid();
surfaceDestroyed = hadSurface && !mSurface.isValid();
surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId())
@@ -2677,10 +2675,6 @@ public final class ViewRootImpl implements ViewParent,
// hierarchy is measured below.
dispatchApplyInsets = true;
}
- if (colorModeChanged && mAttachInfo.mThreadedRenderer != null) {
- mAttachInfo.mThreadedRenderer.setWideGamut(
- lp.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
- }
if (surfaceCreated) {
// If we are creating a new surface, then we need to
@@ -2725,7 +2719,7 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mThreadedRenderer.destroy();
}
} else if ((surfaceReplaced
- || surfaceSizeChanged || windowRelayoutWasForced || colorModeChanged)
+ || surfaceSizeChanged || windowRelayoutWasForced)
&& mSurfaceHolder == null
&& mAttachInfo.mThreadedRenderer != null
&& mSurface.isValid()) {
@@ -4557,18 +4551,16 @@ public final class ViewRootImpl implements ViewParent,
}
}
- private boolean hasColorModeChanged(int colorMode) {
+ private void updateColorModeIfNeeded(int colorMode) {
if (mAttachInfo.mThreadedRenderer == null) {
- return false;
- }
- final boolean isWideGamut = colorMode == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
- if (mAttachInfo.mThreadedRenderer.isWideGamut() == isWideGamut) {
- return false;
+ return;
}
- if (isWideGamut && !mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
- return false;
+ // TODO: Centralize this sanitization? Why do we let setting bad modes?
+ // Alternatively, can we just let HWUI figure it out? Do we need to care here?
+ if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
+ colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
}
- return true;
+ mAttachInfo.mThreadedRenderer.setColorMode(colorMode);
}
@Override
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 446e7aa67bc5..1dbf37aca689 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -27,6 +27,7 @@ import android.annotation.Nullable;
import android.annotation.StyleRes;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.annotation.UiContext;
import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -280,6 +281,7 @@ public abstract class Window {
public static final int DECOR_CAPTION_SHADE_DARK = 2;
@UnsupportedAppUsage
+ @UiContext
private final Context mContext;
@UnsupportedAppUsage
@@ -722,7 +724,7 @@ public abstract class Window {
}
- public Window(Context context) {
+ public Window(@UiContext Context context) {
mContext = context;
mFeatures = mLocalFeatures = getDefaultFeatures(context);
}
@@ -733,6 +735,7 @@ public abstract class Window {
*
* @return Context The Context that was supplied to the constructor.
*/
+ @UiContext
public final Context getContext() {
return mContext;
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index cf4315fc7c00..7923ff0991d8 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -347,6 +347,7 @@ public interface WindowManager extends ViewManager {
TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE,
TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION,
TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER,
+ TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION
})
@Retention(RetentionPolicy.SOURCE)
@interface TransitionFlags {}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index b4561c5795b9..27fbfb6d4d17 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import android.annotation.NonNull;
+import android.annotation.UiContext;
import android.app.ResourcesManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -69,6 +70,7 @@ import java.util.List;
public final class WindowManagerImpl implements WindowManager {
@UnsupportedAppUsage
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
+ @UiContext
@VisibleForTesting
public final Context mContext;
private final Window mParentWindow;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 708e27771ef2..2d0f05e3dc02 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1768,7 +1768,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* <strong>Note:</strong> The primary usage of this API is for UI test automation
* and in order to report the fully qualified view id if an {@link AccessibilityNodeInfo}
* the client has to set the {@link AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
- * flag when configuring their {@link android.accessibilityservice.AccessibilityService}.
+ * flag when configuring the {@link android.accessibilityservice.AccessibilityService}.
* </p>
* <p>
* <strong>Note:</strong> If this view hierarchy has a {@link SurfaceView} embedding another
@@ -3206,7 +3206,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* <strong>Note:</strong> The primary usage of this API is for UI test automation
* and in order to report the source view id of an {@link AccessibilityNodeInfo} the
* client has to set the {@link AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
- * flag when configuring their {@link android.accessibilityservice.AccessibilityService}.
+ * flag when configuring the {@link android.accessibilityservice.AccessibilityService}.
* </p>
* @return The id resource name.
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
index cce109074d82..6300320f5eb5 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
@@ -47,6 +47,9 @@ public final class InlineSuggestionsRequest implements Parcelable {
/**
* Max number of suggestions expected from the response. It must be a positive value.
* Defaults to {@code SUGGESTION_COUNT_UNLIMITED} if not set.
+ *
+ * <p>In practice, it is recommended that the max suggestion count does not exceed <b>5</b>
+ * for performance reasons.</p>
*/
private final int mMaxSuggestionCount;
@@ -67,6 +70,9 @@ public final class InlineSuggestionsRequest implements Parcelable {
/**
* The IME provided locales for the request. If non-empty, the inline suggestions should
* return languages from the supported locales. If not provided, it'll default to system locale.
+ *
+ * <p>Note for Autofill Providers: It is <b>recommended</b> for the returned inline suggestions
+ * to have one locale to guarantee consistent UI rendering.</p>
*/
private @NonNull LocaleList mSupportedLocales;
@@ -227,6 +233,9 @@ public final class InlineSuggestionsRequest implements Parcelable {
/**
* Max number of suggestions expected from the response. It must be a positive value.
* Defaults to {@code SUGGESTION_COUNT_UNLIMITED} if not set.
+ *
+ * <p>In practice, it is recommended that the max suggestion count does not exceed <b>5</b>
+ * for performance reasons.</p>
*/
@DataClass.Generated.Member
public int getMaxSuggestionCount() {
@@ -256,6 +265,9 @@ public final class InlineSuggestionsRequest implements Parcelable {
/**
* The IME provided locales for the request. If non-empty, the inline suggestions should
* return languages from the supported locales. If not provided, it'll default to system locale.
+ *
+ * <p>Note for Autofill Providers: It is <b>recommended</b> for the returned inline suggestions
+ * to have one locale to guarantee consistent UI rendering.</p>
*/
@DataClass.Generated.Member
public @NonNull LocaleList getSupportedLocales() {
@@ -458,6 +470,9 @@ public final class InlineSuggestionsRequest implements Parcelable {
/**
* Max number of suggestions expected from the response. It must be a positive value.
* Defaults to {@code SUGGESTION_COUNT_UNLIMITED} if not set.
+ *
+ * <p>In practice, it is recommended that the max suggestion count does not exceed <b>5</b>
+ * for performance reasons.</p>
*/
@DataClass.Generated.Member
public @NonNull Builder setMaxSuggestionCount(int value) {
@@ -508,6 +523,9 @@ public final class InlineSuggestionsRequest implements Parcelable {
/**
* The IME provided locales for the request. If non-empty, the inline suggestions should
* return languages from the supported locales. If not provided, it'll default to system locale.
+ *
+ * <p>Note for Autofill Providers: It is <b>recommended</b> for the returned inline suggestions
+ * to have one locale to guarantee consistent UI rendering.</p>
*/
@DataClass.Generated.Member
public @NonNull Builder setSupportedLocales(@NonNull LocaleList value) {
@@ -604,7 +622,7 @@ public final class InlineSuggestionsRequest implements Parcelable {
}
@DataClass.Generated(
- time = 1588109685838L,
+ time = 1595457701315L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java",
inputSignatures = "public static final int SUGGESTION_COUNT_UNLIMITED\nprivate final int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate int mHostDisplayId\npublic void setHostInputToken(android.os.IBinder)\nprivate boolean extrasEquals(android.os.Bundle)\nprivate void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic void setHostDisplayId(int)\nprivate void onConstructed()\npublic void filterContentTypes()\nprivate static int defaultMaxSuggestionCount()\nprivate static java.lang.String defaultHostPackageName()\nprivate static android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsResponse.java b/core/java/android/view/inputmethod/InlineSuggestionsResponse.java
index be833df61ec4..b393c67d7876 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsResponse.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsResponse.java
@@ -32,7 +32,18 @@ import java.util.List;
*/
@DataClass(genEqualsHashCode = true, genToString = true, genHiddenConstructor = true)
public final class InlineSuggestionsResponse implements Parcelable {
- private final @NonNull List<InlineSuggestion> mInlineSuggestions;
+ /**
+ * List of {@link InlineSuggestion}s returned as a part of this response.
+ *
+ * <p>When the host app requests to inflate this <b>ordered</b> list of inline suggestions by
+ * calling {@link InlineSuggestion#inflate}, it is the host's responsibility to track the
+ * order of the inflated {@link android.view.View}s. These views are to be added in
+ * order to the view hierarchy, because the inflation calls will return asynchronously.</p>
+ *
+ * <p>The inflation ordering does not apply to the pinned icon.</p>
+ */
+ @NonNull
+ private final List<InlineSuggestion> mInlineSuggestions;
/**
* Creates a new {@link InlineSuggestionsResponse}, for testing purpose.
@@ -48,7 +59,7 @@ public final class InlineSuggestionsResponse implements Parcelable {
- // Code below generated by codegen v1.0.14.
+ // Code below generated by codegen v1.0.15.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -64,6 +75,15 @@ public final class InlineSuggestionsResponse implements Parcelable {
/**
* Creates a new InlineSuggestionsResponse.
*
+ * @param inlineSuggestions
+ * List of {@link InlineSuggestion}s returned as a part of this response.
+ *
+ * <p>When the host app requests to inflate this <b>ordered</b> list of inline suggestions by
+ * calling {@link InlineSuggestion#inflate}, it is the host's responsibility to track the
+ * order of the inflated {@link android.view.View}s. These views are to be added in
+ * order to the view hierarchy, because the inflation calls will return asynchronously.</p>
+ *
+ * <p>The inflation ordering does not apply to the pinned icon.</p>
* @hide
*/
@DataClass.Generated.Member
@@ -76,6 +96,16 @@ public final class InlineSuggestionsResponse implements Parcelable {
// onConstructed(); // You can define this method to get a callback
}
+ /**
+ * List of {@link InlineSuggestion}s returned as a part of this response.
+ *
+ * <p>When the host app requests to inflate this <b>ordered</b> list of inline suggestions by
+ * calling {@link InlineSuggestion#inflate}, it is the host's responsibility to track the
+ * order of the inflated {@link android.view.View}s. These views are to be added in
+ * order to the view hierarchy, because the inflation calls will return asynchronously.</p>
+ *
+ * <p>The inflation ordering does not apply to the pinned icon.</p>
+ */
@DataClass.Generated.Member
public @NonNull List<InlineSuggestion> getInlineSuggestions() {
return mInlineSuggestions;
@@ -164,8 +194,8 @@ public final class InlineSuggestionsResponse implements Parcelable {
};
@DataClass.Generated(
- time = 1578972149519L,
- codegenVersion = "1.0.14",
+ time = 1595891876037L,
+ codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsResponse.java",
inputSignatures = "private final @android.annotation.NonNull java.util.List<android.view.inputmethod.InlineSuggestion> mInlineSuggestions\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestionsResponse newInlineSuggestionsResponse(java.util.List<android.view.inputmethod.InlineSuggestion>)\nclass InlineSuggestionsResponse extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)")
@Deprecated
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 793d94097862..f6671d86cf7b 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -22,6 +22,7 @@ import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION;
+import android.annotation.DisplayContext;
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1193,7 +1194,7 @@ public final class InputMethodManager {
* @hide
*/
@NonNull
- public static InputMethodManager forContext(Context context) {
+ public static InputMethodManager forContext(@DisplayContext Context context) {
final int displayId = context.getDisplayId();
// For better backward compatibility, we always use Looper.getMainLooper() for the default
// display case.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 16e87f8bca9a..97e0689ce64f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1514,7 +1514,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mOnScrollListener != null) {
mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
}
- onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
+ // placeholder values, View's implementation does not use these.
+ onScrollChanged(0, 0, 0, 0);
}
/**
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 8c0061d6e750..d969a8894181 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -431,7 +431,8 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
mSelectedCenterOffset = childLeft + childCenter - galleryCenter;
}
- onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
+ // placeholder values, View's implementation does not use these.
+ onScrollChanged(0, 0, 0, 0);
invalidate();
}
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index e58f08a79965..b4379ec75205 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -505,7 +505,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
public void reset() {
count = 0;
- // by default there is at least one dummy view type
+ // by default there is at least one placeholder view type
viewTypeCount = 1;
hasStableIds = true;
loadingTemplate = null;
@@ -948,7 +948,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
private void updateTemporaryMetaData(IRemoteViewsFactory factory) {
try {
// get the properties/first view (so that we can use it to
- // measure our dummy views)
+ // measure our placeholder views)
boolean hasStableIds = factory.hasStableIds();
int viewTypeCount = factory.getViewTypeCount();
int count = factory.getCount();
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 6ef570cdc784..2eadb56c0f36 100755
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1789,7 +1789,7 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
return createIntent(action, dataUri, extraData, query, actionKey, actionMsg);
} catch (RuntimeException e ) {
int rowNum;
- try { // be really paranoid now
+ try { // be really defensive now
rowNum = c.getPosition();
} catch (RuntimeException e2 ) {
rowNum = -1;
diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING
index f089f48368a0..df3024eda4b6 100644
--- a/core/java/android/widget/TEST_MAPPING
+++ b/core/java/android/widget/TEST_MAPPING
@@ -17,6 +17,45 @@
}
],
"file_patterns": ["Toast\\.java"]
+ },
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.LoginActivityTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.AppModeFull"
+ }
+ ]
+ },
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.AutofillValueTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.CheckoutActivityTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.AppModeFull"
+ }
+ ]
}
]
}
diff --git a/core/java/android/widget/inline/InlineContentView.java b/core/java/android/widget/inline/InlineContentView.java
index 9712311aab7c..699a7735bbee 100644
--- a/core/java/android/widget/inline/InlineContentView.java
+++ b/core/java/android/widget/inline/InlineContentView.java
@@ -59,7 +59,7 @@ import java.util.function.Consumer;
*/
public class InlineContentView extends ViewGroup {
- private static final String TAG = "InlineContentView";
+ private static final String TAG = "InlineContentView_test2";
private static final boolean DEBUG = false;
diff --git a/core/java/android/widget/inline/TEST_MAPPING b/core/java/android/widget/inline/TEST_MAPPING
new file mode 100644
index 000000000000..0baad5c31af9
--- /dev/null
+++ b/core/java/android/widget/inline/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.inline"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 6fdb182e5a62..105e05a4a6c3 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -16,6 +16,8 @@
package com.android.internal.app;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.IActivityManager;
@@ -29,6 +31,7 @@ import android.os.Bundle;
import android.os.LocaleList;
import android.os.RemoteException;
import android.provider.Settings;
+import android.sysprop.LocalizationProperties;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -44,6 +47,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
public class LocalePicker extends ListFragment {
private static final String TAG = "LocalePicker";
@@ -93,7 +99,38 @@ public class LocalePicker extends ListFragment {
}
public static String[] getSupportedLocales(Context context) {
- return context.getResources().getStringArray(R.array.supported_locales);
+ String[] allLocales = context.getResources().getStringArray(R.array.supported_locales);
+
+ Predicate<String> localeFilter = getLocaleFilter();
+ if (localeFilter == null) {
+ return allLocales;
+ }
+
+ List<String> result = new ArrayList<>(allLocales.length);
+ for (String locale : allLocales) {
+ if (localeFilter.test(locale)) {
+ result.add(locale);
+ }
+ }
+
+ int localeCount = result.size();
+ return (localeCount == allLocales.length) ? allLocales
+ : result.toArray(new String[localeCount]);
+ }
+
+ @Nullable
+ private static Predicate<String> getLocaleFilter() {
+ try {
+ return LocalizationProperties.locale_filter()
+ .map(filter -> Pattern.compile(filter).asPredicate())
+ .orElse(null);
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to read locale filter.", e);
+ } catch (PatternSyntaxException e) {
+ Log.e(TAG, "Bad locale filter format (\"" + e.getPattern() + "\"), skipping.");
+ }
+
+ return null;
}
public static List<LocaleInfo> getAllAssetLocales(Context context, boolean isInDeveloperMode) {
@@ -266,6 +303,11 @@ public class LocalePicker extends ListFragment {
*/
@UnsupportedAppUsage
public static void updateLocales(LocaleList locales) {
+ if (locales != null) {
+ locales = removeExcludedLocales(locales);
+ }
+ // Note: the empty list case is covered by Configuration.setLocales().
+
try {
final IActivityManager am = ActivityManager.getService();
final Configuration config = am.getConfiguration();
@@ -282,6 +324,26 @@ public class LocalePicker extends ListFragment {
}
}
+ @NonNull
+ private static LocaleList removeExcludedLocales(@NonNull LocaleList locales) {
+ Predicate<String> localeFilter = getLocaleFilter();
+ if (localeFilter == null) {
+ return locales;
+ }
+
+ int localeCount = locales.size();
+ ArrayList<Locale> filteredLocales = new ArrayList<>(localeCount);
+ for (int i = 0; i < localeCount; ++i) {
+ Locale locale = locales.get(i);
+ if (localeFilter.test(locale.toString())) {
+ filteredLocales.add(locale);
+ }
+ }
+
+ return (localeCount == filteredLocales.size()) ? locales
+ : new LocaleList(filteredLocales.toArray(new Locale[0]));
+ }
+
/**
* Get the locale list.
*
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 7195b45a4055..b2852eaeef2a 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -437,7 +437,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
mBinding = true;
final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
- | mBindingFlags;
+ | Context.BIND_INCLUDE_CAPABILITIES | mBindingFlags;
final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
mHandler, new UserHandle(mUserId));
diff --git a/core/java/com/android/internal/os/ChildZygoteInit.java b/core/java/com/android/internal/os/ChildZygoteInit.java
index 1f816c18f886..749ff84358d9 100644
--- a/core/java/com/android/internal/os/ChildZygoteInit.java
+++ b/core/java/com/android/internal/os/ChildZygoteInit.java
@@ -116,7 +116,7 @@ public class ChildZygoteInit {
try {
server.registerServerSocketAtAbstractName(socketName);
- // Add the abstract socket to the FD whitelist so that the native zygote code
+ // Add the abstract socket to the FD allow list so that the native zygote code
// can properly detach it after forking.
Zygote.nativeAllowFileAcrossFork("ABSTRACT/" + socketName);
diff --git a/core/java/com/android/internal/os/OWNERS b/core/java/com/android/internal/os/OWNERS
index 928310549e6e..afc94329dc4d 100644
--- a/core/java/com/android/internal/os/OWNERS
+++ b/core/java/com/android/internal/os/OWNERS
@@ -1 +1 @@
-per-file ZygoteArguments.java,ZygoteConnection.java,ZygoteInit.java,Zygote.java,ZygoteServer.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+per-file ZygoteArguments.java,ZygoteConnection.java,ZygoteInit.java,Zygote.java,ZygoteServer.java = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 2989a5eb99b2..1ca9250f2d27 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -816,9 +816,9 @@ public final class Zygote {
throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-app");
} else if (args.mStartChildZygote) {
throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--start-child-zygote");
- } else if (args.mApiBlacklistExemptions != null) {
+ } else if (args.mApiDenylistExemptions != null) {
throw new IllegalArgumentException(
- USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions");
+ USAP_ERROR_PREFIX + "--set-api-denylist-exemptions");
} else if (args.mHiddenApiAccessLogSampleRate != -1) {
throw new IllegalArgumentException(
USAP_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index 94c1f71a26db..22082d02d9f6 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -192,10 +192,10 @@ class ZygoteArguments {
boolean mBootCompleted;
/**
- * Exemptions from API blacklisting. These are sent to the pre-forked zygote at boot time, or
- * when they change, via --set-api-blacklist-exemptions.
+ * Exemptions from API deny-listing. These are sent to the pre-forked zygote at boot time, or
+ * when they change, via --set-api-denylist-exemptions.
*/
- String[] mApiBlacklistExemptions;
+ String[] mApiDenylistExemptions;
/**
* Sampling rate for logging hidden API accesses to the event log. This is sent to the
@@ -416,10 +416,10 @@ class ZygoteArguments {
expectRuntimeArgs = false;
} else if (arg.equals("--start-child-zygote")) {
mStartChildZygote = true;
- } else if (arg.equals("--set-api-blacklist-exemptions")) {
+ } else if (arg.equals("--set-api-denylist-exemptions")) {
// consume all remaining args; this is a stand-alone command, never included
// with the regular fork command.
- mApiBlacklistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
+ mApiDenylistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
curArg = args.length;
expectRuntimeArgs = false;
} else if (arg.startsWith("--hidden-api-log-sampling-rate=")) {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index ec1b05a455f1..5a576ebbc442 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -185,8 +185,8 @@ class ZygoteConnection {
return null;
}
- if (parsedArgs.mApiBlacklistExemptions != null) {
- return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions);
+ if (parsedArgs.mApiDenylistExemptions != null) {
+ return handleApiDenylistExemptions(zygoteServer, parsedArgs.mApiDenylistExemptions);
}
if (parsedArgs.mHiddenApiAccessLogSampleRate != -1
@@ -367,11 +367,11 @@ class ZygoteConnection {
}
/**
- * Makes the necessary changes to implement a new API blacklist exemption policy, and then
+ * Makes the necessary changes to implement a new API deny list exemption policy, and then
* responds to the system server, letting it know that the task has been completed.
*
* This necessitates a change to the internal state of the Zygote. As such, if the USAP
- * pool is enabled all existing USAPs have an incorrect API blacklist exemption list. To
+ * pool is enabled all existing USAPs have an incorrect API deny list exemption list. To
* properly handle this request the pool must be emptied and refilled. This process can return
* a Runnable object that must be returned to ZygoteServer.runSelectLoop to be invoked.
*
@@ -380,9 +380,9 @@ class ZygoteConnection {
* @return A Runnable object representing a new app in any USAPs spawned from here; the
* zygote process will always receive a null value from this function.
*/
- private Runnable handleApiBlacklistExemptions(ZygoteServer zygoteServer, String[] exemptions) {
+ private Runnable handleApiDenylistExemptions(ZygoteServer zygoteServer, String[] exemptions) {
return stateChangeWithUsapPoolReset(zygoteServer,
- () -> ZygoteInit.setApiBlacklistExemptions(exemptions));
+ () -> ZygoteInit.setApiDenylistExemptions(exemptions));
}
private Runnable handleUsapPoolStatusChange(ZygoteServer zygoteServer, boolean newStatus) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 5fd93339570b..32e7fdc51d6c 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -583,7 +583,10 @@ public class ZygoteInit {
VMRuntime.registerAppInfo(profilePath, codePaths);
}
- public static void setApiBlacklistExemptions(String[] exemptions) {
+ /**
+ * Sets the list of classes/methods for the hidden API
+ */
+ public static void setApiDenylistExemptions(String[] exemptions) {
VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
}
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index a0b50df52e86..bb1733738643 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -451,7 +451,7 @@ class ZygoteServer {
* For reasons of correctness the USAP pool pipe and event FDs
* must be processed before the session and server sockets. This
* is to ensure that the USAP pool accounting information is
- * accurate when handling other requests like API blacklist
+ * accurate when handling other requests like API deny list
* exemptions.
*/
diff --git a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
index 0e703fa686e0..205c5fd735ea 100644
--- a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
+++ b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
@@ -103,8 +103,11 @@ public class GestureNavigationSettingsObserver extends ContentObserver {
final DisplayMetrics dm = userRes.getDisplayMetrics();
final float defaultInset = userRes.getDimension(
com.android.internal.R.dimen.config_backGestureInset) / dm.density;
- final float backGestureInset = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
- BACK_GESTURE_EDGE_WIDTH, defaultInset);
+ // Only apply the back gesture config if there is an existing inset
+ final float backGestureInset = defaultInset > 0
+ ? DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
+ BACK_GESTURE_EDGE_WIDTH, defaultInset)
+ : defaultInset;
final float inset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, backGestureInset,
dm);
final float scale = Settings.Secure.getFloatForUser(
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 0a3fe096279d..053b06f3d407 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -35,6 +35,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BA
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiContext;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.SearchManager;
@@ -342,7 +343,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
static final RotationWatcher sRotationWatcher = new RotationWatcher();
@UnsupportedAppUsage
- public PhoneWindow(Context context) {
+ public PhoneWindow(@UiContext Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
mRenderShadowsInCompositor = Settings.Global.getInt(context.getContentResolver(),
@@ -352,7 +353,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
/**
* Constructor for main window of an activity.
*/
- public PhoneWindow(Context context, Window preservedWindow,
+ public PhoneWindow(@UiContext Context context, Window preservedWindow,
ActivityConfigCallback activityConfigCallback) {
this(context);
// Only main activity windows use decor context, all the other windows depend on whatever
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 5a04992a35b4..ea09fc8cd34a 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -65,9 +65,7 @@ interface ITelephonyRegistry {
void notifyDataActivity(int state);
void notifyDataActivityForSubscriber(in int subId, int state);
void notifyDataConnectionForSubscriber(
- int phoneId, int subId, int apnType, in PreciseDataConnectionState preciseState);
- @UnsupportedAppUsage
- void notifyDataConnectionFailed(String apnType);
+ int phoneId, int subId, in PreciseDataConnectionState preciseState);
// Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
void notifyCellLocation(in CellIdentity cellLocation);
void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation);
@@ -77,8 +75,6 @@ interface ITelephonyRegistry {
int foregroundCallState, int backgroundCallState);
void notifyDisconnectCause(int phoneId, int subId, int disconnectCause,
int preciseDisconnectCause);
- void notifyPreciseDataConnectionFailed(int phoneId, int subId, int apnType, String apn,
- int failCause);
void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo);
void notifySrvccStateChanged(in int subId, in int lteState);
void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId,
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index c6a1153c747f..6b754ca301f3 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -19,6 +19,7 @@ package com.android.server;
import static com.android.internal.util.ArrayUtils.appendInt;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.pm.FeatureInfo;
@@ -245,6 +246,14 @@ public class SystemConfig {
*/
private Map<String, Map<String, String>> mNamedActors = null;
+ // Package name of the package pre-installed on a read-only
+ // partition that is used to verify if an overlay package fulfills
+ // the 'config_signature' policy by comparing their signatures:
+ // if the overlay package is signed with the same certificate as
+ // the package declared in 'config-signature' tag, then the
+ // overlay package fulfills the 'config_signature' policy.
+ private String mOverlayConfigSignaturePackage;
+
public static SystemConfig getInstance() {
if (!isSystemProcess()) {
Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
@@ -432,6 +441,12 @@ public class SystemConfig {
return mNamedActors != null ? mNamedActors : Collections.emptyMap();
}
+ @Nullable
+ public String getOverlayConfigSignaturePackage() {
+ return TextUtils.isEmpty(mOverlayConfigSignaturePackage)
+ ? null : mOverlayConfigSignaturePackage;
+ }
+
/**
* Only use for testing. Do NOT use in production code.
* @param readPermissions false to create an empty SystemConfig; true to read the permissions.
@@ -1137,6 +1152,27 @@ public class SystemConfig {
}
XmlUtils.skipCurrentTag(parser);
} break;
+ case "overlay-config-signature": {
+ if (allowAll) {
+ String pkgName = parser.getAttributeValue(null, "package");
+ if (pkgName == null) {
+ Slog.w(TAG, "<" + name + "> without package in " + permFile
+ + " at " + parser.getPositionDescription());
+ } else {
+ if (TextUtils.isEmpty(mOverlayConfigSignaturePackage)) {
+ mOverlayConfigSignaturePackage = pkgName.intern();
+ } else {
+ throw new IllegalStateException("Reference signature package "
+ + "defined as both "
+ + mOverlayConfigSignaturePackage
+ + " and " + pkgName);
+ }
+ }
+ } else {
+ logNotAllowedInPartition(name, permFile, parser);
+ }
+ XmlUtils.skipCurrentTag(parser);
+ } break;
case "rollback-whitelisted-app": {
String pkgname = parser.getAttributeValue(null, "package");
if (pkgname == null) {
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index d7d8621a3640..7d80993afc6e 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -17,4 +17,4 @@ per-file android_view_*MotionEvent.* = michaelwr@google.com, svv@google.com
per-file android_view_PointerIcon.* = michaelwr@google.com, svv@google.com
# Zygote
-per-file com_android_internal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+per-file com_android_internal_os_Zygote.*,fd_utils.* = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
diff --git a/core/jni/android_hardware_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
index 350f35828418..ff73c74e125e 100644
--- a/core/jni/android_hardware_input_InputApplicationHandle.cpp
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -61,8 +61,8 @@ bool NativeInputApplicationHandle::updateInfo() {
mInfo.name = getStringField(env, obj, gInputApplicationHandleClassInfo.name, "<null>");
- mInfo.dispatchingTimeout = decltype(mInfo.dispatchingTimeout)(
- env->GetLongField(obj, gInputApplicationHandleClassInfo.dispatchingTimeoutNanos));
+ mInfo.dispatchingTimeoutNanos =
+ env->GetLongField(obj, gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
jobject tokenObj = env->GetObjectField(obj,
gInputApplicationHandleClassInfo.token);
@@ -77,32 +77,28 @@ bool NativeInputApplicationHandle::updateInfo() {
return mInfo.token.get() != nullptr;
}
-
// --- Global functions ---
-sp<InputApplicationHandle> android_view_InputApplicationHandle_getHandle(
+std::shared_ptr<InputApplicationHandle> android_view_InputApplicationHandle_getHandle(
JNIEnv* env, jobject inputApplicationHandleObj) {
if (!inputApplicationHandleObj) {
return NULL;
}
AutoMutex _l(gHandleMutex);
-
jlong ptr = env->GetLongField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr);
- NativeInputApplicationHandle* handle;
+ std::shared_ptr<NativeInputApplicationHandle>* handle;
if (ptr) {
- handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr);
+ handle = reinterpret_cast<std::shared_ptr<NativeInputApplicationHandle>*>(ptr);
} else {
jweak objWeak = env->NewWeakGlobalRef(inputApplicationHandleObj);
- handle = new NativeInputApplicationHandle(objWeak);
- handle->incStrong((void*)android_view_InputApplicationHandle_getHandle);
+ handle = new std::shared_ptr(std::make_shared<NativeInputApplicationHandle>(objWeak));
env->SetLongField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr,
reinterpret_cast<jlong>(handle));
}
- return handle;
+ return *handle;
}
-
// --- JNI ---
static void android_view_InputApplicationHandle_nativeDispose(JNIEnv* env, jobject obj) {
@@ -112,8 +108,9 @@ static void android_view_InputApplicationHandle_nativeDispose(JNIEnv* env, jobje
if (ptr) {
env->SetLongField(obj, gInputApplicationHandleClassInfo.ptr, 0);
- NativeInputApplicationHandle* handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr);
- handle->decStrong((void*)android_view_InputApplicationHandle_getHandle);
+ std::shared_ptr<NativeInputApplicationHandle>* handle =
+ reinterpret_cast<std::shared_ptr<NativeInputApplicationHandle>*>(ptr);
+ delete handle;
}
}
diff --git a/core/jni/android_hardware_input_InputApplicationHandle.h b/core/jni/android_hardware_input_InputApplicationHandle.h
index 52ab3e614ba1..ec99d6da5b8e 100644
--- a/core/jni/android_hardware_input_InputApplicationHandle.h
+++ b/core/jni/android_hardware_input_InputApplicationHandle.h
@@ -39,8 +39,7 @@ private:
jweak mObjWeak;
};
-
-extern sp<InputApplicationHandle> android_view_InputApplicationHandle_getHandle(
+extern std::shared_ptr<InputApplicationHandle> android_view_InputApplicationHandle_getHandle(
JNIEnv* env, jobject inputApplicationHandleObj);
} // namespace android
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index bdb4544f4aae..796c5c4cc521 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -168,8 +168,8 @@ bool NativeInputWindowHandle::updateInfo() {
jobject inputApplicationHandleObj = env->GetObjectField(obj,
gInputWindowHandleClassInfo.inputApplicationHandle);
if (inputApplicationHandleObj) {
- sp<InputApplicationHandle> inputApplicationHandle =
- android_view_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
+ std::shared_ptr<InputApplicationHandle> inputApplicationHandle =
+ android_view_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
if (inputApplicationHandle != nullptr) {
inputApplicationHandle->updateInfo();
mInfo.applicationInfo = *(inputApplicationHandle->getInfo());
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 22bb2102a6e1..1f625443c96e 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -974,7 +974,7 @@ static jint convertAudioPortConfigFromNative(JNIEnv *env,
if (jHandle == NULL) {
return (jint)AUDIO_JAVA_ERROR;
}
- // create dummy port and port config objects with just the correct handle
+ // create placeholder port and port config objects with just the correct handle
// and configuration data. The actual AudioPortConfig objects will be
// constructed by java code with correct class type (device, mix etc...)
// and reference to AudioPort instance in this client
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index e56809f66dc7..8d4c4e5311f8 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -93,13 +93,13 @@ static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz,
static void android_net_utils_detachBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
{
- int dummy = 0;
+ int optval_ignored = 0;
int fd = jniGetFDFromFileDescriptor(env, javaFd);
- if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)) != 0) {
+ if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &optval_ignored, sizeof(optval_ignored)) !=
+ 0) {
jniThrowExceptionFmt(env, "java/net/SocketException",
"setsockopt(SO_DETACH_FILTER): %s", strerror(errno));
}
-
}
static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index d6e8531fa6ca..ef0eeec2c7af 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -920,7 +920,7 @@ int register_android_os_Debug(JNIEnv *env)
{
jclass clazz = env->FindClass("android/os/Debug$MemoryInfo");
- // Sanity check the number of other statistics expected in Java matches here.
+ // Check the number of other statistics expected in Java matches here.
jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I");
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 2000ecbbcf89..7cfe3bc1020a 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -330,7 +330,7 @@ static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, j
if (parcel != NULL) {
int32_t len = parcel->readInt32();
- // sanity check the stored length against the true data size
+ // Validate the stored length against the true data size
if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
ret = env->NewByteArray(len);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 885b0a33e43c..e1180384fcc9 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -962,7 +962,7 @@ static jlong android_os_Binder_clearCallingIdentity()
static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
{
- // XXX temporary sanity check to debug crashes.
+ // XXX temporary validation check to debug crashes.
int uid = (int)(token>>32);
if (uid > 0 && uid < 999) {
// In Android currently there are no uids in this range.
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
index 24c3ff80badd..70a9be740810 100644
--- a/core/jni/android_view_InputQueue.cpp
+++ b/core/jni/android_view_InputQueue.cpp
@@ -176,8 +176,8 @@ void InputQueue::enqueueEvent(InputEvent* event) {
Mutex::Autolock _l(mLock);
mPendingEvents.push(event);
if (mPendingEvents.size() == 1) {
- char dummy = 0;
- int res = TEMP_FAILURE_RETRY(write(mDispatchWriteFd, &dummy, sizeof(dummy)));
+ char payload = '\0';
+ int res = TEMP_FAILURE_RETRY(write(mDispatchWriteFd, &payload, sizeof(payload)));
if (res < 0 && errno != EAGAIN) {
ALOGW("Failed writing to dispatch fd: %s", strerror(errno));
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a965ab310205..814a07e7f2df 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -104,6 +104,27 @@ static struct {
jfieldID top;
} gRectClassInfo;
+static struct {
+ jfieldID pixelFormat;
+ jfieldID sourceCrop;
+ jfieldID frameScale;
+ jfieldID captureSecureLayers;
+} gCaptureArgsClassInfo;
+
+static struct {
+ jfieldID displayToken;
+ jfieldID width;
+ jfieldID height;
+ jfieldID useIdentityTransform;
+ jfieldID rotation;
+} gDisplayCaptureArgsClassInfo;
+
+static struct {
+ jfieldID layer;
+ jfieldID excludeLayers;
+ jfieldID childrenOnly;
+} gLayerCaptureArgsClassInfo;
+
// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
void DeleteScreenshot(void* addr, void* context) {
delete ((ScreenshotClient*) context);
@@ -276,55 +297,79 @@ static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
return Rect(left, top, right, bottom);
}
-static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
- jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
- bool useIdentityTransform, int rotation, bool captureSecureLayers) {
- sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
- if (displayToken == NULL) {
+static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& captureArgs) {
+ captureArgs.pixelFormat = static_cast<ui::PixelFormat>(
+ env->GetIntField(captureArgsObject, gCaptureArgsClassInfo.pixelFormat));
+ captureArgs.sourceCrop =
+ rectFromObj(env,
+ env->GetObjectField(captureArgsObject, gCaptureArgsClassInfo.sourceCrop));
+ captureArgs.frameScale =
+ env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale);
+ captureArgs.captureSecureLayers =
+ env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
+}
+
+static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
+ jobject displayCaptureArgsObject) {
+ DisplayCaptureArgs captureArgs;
+ getCaptureArgs(env, displayCaptureArgsObject, captureArgs);
+
+ captureArgs.displayToken =
+ ibinderForJavaObject(env,
+ env->GetObjectField(displayCaptureArgsObject,
+ gDisplayCaptureArgsClassInfo.displayToken));
+ captureArgs.width =
+ env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width);
+ captureArgs.height =
+ env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height);
+ captureArgs.useIdentityTransform =
+ env->GetBooleanField(displayCaptureArgsObject,
+ gDisplayCaptureArgsClassInfo.useIdentityTransform);
+ captureArgs.rotation = ui::toRotation(
+ env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.rotation));
+ return captureArgs;
+}
+
+static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) {
+ const DisplayCaptureArgs captureArgs =
+ displayCaptureArgsFromObject(env, displayCaptureArgsObject);
+
+ if (captureArgs.displayToken == NULL) {
return NULL;
}
- const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
- const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
-
- Rect sourceCrop = rectFromObj(env, sourceCropObj);
- sp<GraphicBuffer> buffer;
- bool capturedSecureLayers = false;
- status_t res = ScreenshotClient::capture(displayToken, dataspace,
- ui::PixelFormat::RGBA_8888,
- sourceCrop, width, height,
- useIdentityTransform, ui::toRotation(rotation),
- captureSecureLayers, &buffer, capturedSecureLayers);
+
+ ScreenCaptureResults captureResults;
+ status_t res = ScreenshotClient::captureDisplay(captureArgs, captureResults);
if (res != NO_ERROR) {
return NULL;
}
- jobject jhardwareBuffer =
- android_hardware_HardwareBuffer_createFromAHardwareBuffer(env,
- buffer->toAHardwareBuffer());
- const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+ jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+ env, captureResults.buffer->toAHardwareBuffer());
+ const jint namedColorSpace =
+ fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer,
- namedColorSpace, capturedSecureLayers);
+ namedColorSpace, captureResults.capturedSecureLayers);
}
-static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
- jlong layerObject, jobject sourceCropObj, jfloat frameScale,
- jlongArray excludeObjectArray, jint format) {
-
- auto layer = reinterpret_cast<SurfaceControl *>(layerObject);
- if (layer == NULL) {
- return NULL;
- }
-
- Rect sourceCrop;
- if (sourceCropObj != NULL) {
- sourceCrop = rectFromObj(env, sourceCropObj);
+static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) {
+ LayerCaptureArgs captureArgs;
+ getCaptureArgs(env, layerCaptureArgsObject, captureArgs);
+ SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
+ env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
+ if (layer == nullptr) {
+ return nullptr;
}
- std::unordered_set<sp<IBinder>,ISurfaceComposer::SpHash<IBinder>> excludeHandles;
+ captureArgs.layerHandle = layer->getHandle();
+ captureArgs.childrenOnly =
+ env->GetBooleanField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.childrenOnly);
+ jlongArray excludeObjectArray = reinterpret_cast<jlongArray>(
+ env->GetObjectField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.excludeLayers));
if (excludeObjectArray != NULL) {
const jsize len = env->GetArrayLength(excludeObjectArray);
- excludeHandles.reserve(len);
+ captureArgs.excludeHandles.reserve(len);
const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
for (jsize i = 0; i < len; i++) {
@@ -333,33 +378,24 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTok
jniThrowNullPointerException(env, "Exclude layer is null");
return NULL;
}
- excludeHandles.emplace(excludeObject->getHandle());
+ captureArgs.excludeHandles.emplace(excludeObject->getHandle());
}
env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
}
- sp<GraphicBuffer> buffer;
- ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
- sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
- if (displayToken != nullptr) {
- const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
- dataspace = pickDataspaceFromColorMode(colorMode);
- }
- status_t res = ScreenshotClient::captureChildLayers(layer->getHandle(), dataspace,
- static_cast<ui::PixelFormat>(format),
- sourceCrop, excludeHandles, frameScale,
- &buffer);
+ ScreenCaptureResults captureResults;
+ status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults);
if (res != NO_ERROR) {
return NULL;
}
- jobject jhardwareBuffer =
- android_hardware_HardwareBuffer_createFromAHardwareBuffer(env,
- buffer->toAHardwareBuffer());
- const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+ jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+ env, captureResults.buffer->toAHardwareBuffer());
+ const jint namedColorSpace =
+ fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer,
- namedColorSpace, false /* capturedSecureLayers */);
+ namedColorSpace, captureResults.capturedSecureLayers);
}
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1614,13 +1650,12 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSeverChildren } ,
{"nativeSetOverrideScalingMode", "(JJI)V",
(void*)nativeSetOverrideScalingMode },
- {"nativeScreenshot",
- "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
+ {"nativeCaptureDisplay",
+ "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)"
"Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
- (void*)nativeScreenshot },
+ (void*)nativeCaptureDisplay },
{"nativeCaptureLayers",
- "(Landroid/os/IBinder;JLandroid/graphics/Rect;"
- "F[JI)"
+ "(Landroid/view/SurfaceControl$LayerCaptureArgs;)"
"Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
(void*)nativeCaptureLayers },
{"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
@@ -1795,6 +1830,36 @@ int register_android_view_SurfaceControl(JNIEnv* env)
gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax =
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMax", "F");
+ jclass captureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$CaptureArgs");
+ gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
+ gCaptureArgsClassInfo.sourceCrop =
+ GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
+ gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F");
+ gCaptureArgsClassInfo.captureSecureLayers =
+ GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
+
+ jclass displayCaptureArgsClazz =
+ FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs");
+ gDisplayCaptureArgsClassInfo.displayToken =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mDisplayToken", "Landroid/os/IBinder;");
+ gDisplayCaptureArgsClassInfo.width =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I");
+ gDisplayCaptureArgsClassInfo.height =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I");
+ gDisplayCaptureArgsClassInfo.useIdentityTransform =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z");
+ gDisplayCaptureArgsClassInfo.rotation =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mRotation", "I");
+
+ jclass layerCaptureArgsClazz =
+ FindClassOrDie(env, "android/view/SurfaceControl$LayerCaptureArgs");
+ gLayerCaptureArgsClassInfo.layer =
+ GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeLayer", "J");
+ gLayerCaptureArgsClassInfo.excludeLayers =
+ GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeExcludeLayers", "[J");
+ gLayerCaptureArgsClassInfo.childrenOnly =
+ GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");
+
return err;
}
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index fe540bb18f42..e4a142b3335b 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -449,7 +449,7 @@ message GlobalSettingsProto {
// Game Driver - List of Apps that are allowed to use Game Driver
optional SettingProto game_driver_allowlist = 12;
// ANGLE - List of Apps that can check ANGLE rules
- optional SettingProto angle_whitelist = 13;
+ optional SettingProto angle_allowlist = 13;
// Game Driver - List of denylists, each denylist is a denylist for
// a specific Game Driver version
optional SettingProto game_driver_denylists = 14;
diff --git a/core/proto/android/server/alarm/alarmmanagerservice.proto b/core/proto/android/server/alarm/alarmmanagerservice.proto
index b74991d525af..e1240245d20f 100644
--- a/core/proto/android/server/alarm/alarmmanagerservice.proto
+++ b/core/proto/android/server/alarm/alarmmanagerservice.proto
@@ -59,9 +59,10 @@ message AlarmManagerServiceDumpProto {
// Time since the last wakeup was set.
optional int64 time_since_last_wakeup_set_ms = 15;
optional int64 time_change_event_count = 16;
- // The current set of user whitelisted apps for device idle mode, meaning
+ // The current set of user exempted apps for device idle mode, meaning
// these are allowed to freely schedule alarms. These are app IDs, not UIDs.
- repeated int32 device_idle_user_whitelist_app_ids = 17;
+ // This field is currently unused.
+ repeated int32 device_idle_user_exempt_app_ids = 17;
repeated AlarmClockMetadataProto next_alarm_clock_metadata = 18;
diff --git a/core/proto/android/server/appstatetracker.proto b/core/proto/android/server/appstatetracker.proto
index 51e88451c7c2..f5583d4f476f 100644
--- a/core/proto/android/server/appstatetracker.proto
+++ b/core/proto/android/server/appstatetracker.proto
@@ -41,14 +41,14 @@ message AppStateTrackerProto {
// UIDs currently in the foreground.
repeated int32 foreground_uids = 11;
- // App ids that are in power-save whitelist.
- repeated int32 power_save_whitelist_app_ids = 3;
+ // App ids that are in power-save exemption list.
+ repeated int32 power_save_exempt_app_ids = 3;
- // App ids that are in power-save user whitelist.
- repeated int32 power_save_user_whitelist_app_ids = 12;
+ // App ids that are in power-save user exemption list.
+ repeated int32 power_save_user_exempt_app_ids = 12;
- // App ids that are in temporary power-save whitelist.
- repeated int32 temp_power_save_whitelist_app_ids = 4;
+ // App ids that are in temporary power-save exemption list.
+ repeated int32 temp_power_save_exempt_app_ids = 4;
message RunAnyInBackgroundRestrictedPackages {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -79,5 +79,5 @@ message AppStateTrackerProto {
}
// Packages that are in the EXEMPT bucket.
- repeated ExemptedPackage exempted_packages = 10;
+ repeated ExemptedPackage exempted_bucket_packages = 10;
}
diff --git a/core/res/res/drawable-car/car_dialog_button_background.xml b/core/res/res/drawable-car/car_dialog_button_background.xml
index a7d40bcd759a..72e5af308c01 100644
--- a/core/res/res/drawable-car/car_dialog_button_background.xml
+++ b/core/res/res/drawable-car/car_dialog_button_background.xml
@@ -16,11 +16,18 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
- <ripple android:color="#4b9eff">
- <item android:id="@android:id/mask">
- <color android:color="@*android:color/car_white_1000"/>
+ <layer-list>
+ <item>
+ <shape android:shape="rectangle">
+ <solid android:color="#3D94CBFF"/>
+ </shape>
</item>
- </ripple>
+ <item>
+ <shape android:shape="rectangle">
+ <stroke android:width="8dp" android:color="#94CBFF"/>
+ </shape>
+ </item>
+ </layer-list>
</item>
<item>
<ripple android:color="?android:attr/colorControlHighlight">
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 6ede806583a5..6307c354317b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1937,7 +1937,7 @@
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de saisie automatique</item>
</plurals>
<string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer dans "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ?"</string>
- <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Enregistrer <xliff:g id="TYPE">%1$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ?"</string>
+ <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Enregistrer la <xliff:g id="TYPE">%1$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Enregistrer <xliff:g id="TYPE_0">%1$s</xliff:g> et <xliff:g id="TYPE_1">%2$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ?"</string>
<string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Enregistrer <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> et <xliff:g id="TYPE_2">%3$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ?"</string>
<string name="autofill_update_title" msgid="3630695947047069136">"Mettre à jour cet élément dans "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ?"</string>
diff --git a/core/sysprop/Android.bp b/core/sysprop/Android.bp
new file mode 100644
index 000000000000..7f20a0ba6642
--- /dev/null
+++ b/core/sysprop/Android.bp
@@ -0,0 +1,21 @@
+// 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.
+
+sysprop_library {
+ name: "com.android.sysprop.localization",
+ srcs: ["LocalizationProperties.sysprop"],
+ property_owner: "Platform",
+ api_packages: ["android.sysprop"],
+ vendor_available: false,
+}
diff --git a/core/sysprop/LocalizationProperties.sysprop b/core/sysprop/LocalizationProperties.sysprop
new file mode 100644
index 000000000000..65f544fa6179
--- /dev/null
+++ b/core/sysprop/LocalizationProperties.sysprop
@@ -0,0 +1,24 @@
+# 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.
+
+module: "android.sysprop.LocalizationProperties"
+owner: Platform
+
+prop {
+ api_name: "locale_filter"
+ type: String
+ prop_name: "ro.localization.locale_filter"
+ scope: Internal
+ access: Readonly
+}
diff --git a/core/sysprop/api/com.android.sysprop.localization-current.txt b/core/sysprop/api/com.android.sysprop.localization-current.txt
new file mode 100644
index 000000000000..fe4f4578683c
--- /dev/null
+++ b/core/sysprop/api/com.android.sysprop.localization-current.txt
@@ -0,0 +1,9 @@
+props {
+ module: "android.sysprop.LocalizationProperties"
+ prop {
+ api_name: "locale_filter"
+ type: String
+ scope: Internal
+ prop_name: "ro.localization.locale_filter"
+ }
+}
diff --git a/core/sysprop/api/com.android.sysprop.localization-latest.txt b/core/sysprop/api/com.android.sysprop.localization-latest.txt
new file mode 100644
index 000000000000..fe4f4578683c
--- /dev/null
+++ b/core/sysprop/api/com.android.sysprop.localization-latest.txt
@@ -0,0 +1,9 @@
+props {
+ module: "android.sysprop.LocalizationProperties"
+ prop {
+ api_name: "locale_filter"
+ type: String
+ scope: Internal
+ prop_name: "ro.localization.locale_filter"
+ }
+}
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index 1edd9623ed2d..e42b4b4ae2bf 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -20,7 +20,11 @@ android_test {
"android.test.runner",
"android.test.base",
],
- static_libs: ["androidx.test.rules", "truth-prebuilt"],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "truth-prebuilt",
+ ],
test_suites: ["general-tests"],
sdk_version: "test_current",
platform_apis: true,
diff --git a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
index 153337727e96..9246a2335050 100644
--- a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
+++ b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
@@ -18,6 +18,8 @@ package com.android.os.bugreports.tests;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.Manifest;
@@ -25,17 +27,27 @@ import android.content.Context;
import android.os.BugreportManager;
import android.os.BugreportManager.BugreportCallback;
import android.os.BugreportParams;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
+import android.os.StrictMode;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExternalResource;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -51,9 +63,11 @@ import java.util.concurrent.TimeUnit;
@RunWith(JUnit4.class)
public class BugreportManagerTest {
@Rule public TestName name = new TestName();
+ @Rule public ExtendedStrictModeVmPolicy mTemporaryVmPolicy = new ExtendedStrictModeVmPolicy();
private static final String TAG = "BugreportManagerTest";
private static final long BUGREPORT_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(10);
+ private static final long UIAUTOMATOR_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
private Handler mHandler;
private Executor mExecutor;
@@ -86,6 +100,8 @@ public class BugreportManagerTest {
@After
public void teardown() throws Exception {
dropPermissions();
+ FileUtils.closeQuietly(mBugreportFd);
+ FileUtils.closeQuietly(mScreenshotFd);
}
@@ -95,47 +111,45 @@ public class BugreportManagerTest {
// wifi bugreport does not take screenshot
mBrm.startBugreport(mBugreportFd, null /*screenshotFd = null*/, wifi(),
mExecutor, callback);
+ shareConsentDialog(ConsentReply.ALLOW);
waitTillDoneOrTimeout(callback);
assertThat(callback.isDone()).isTrue();
// Wifi bugreports should not receive any progress.
assertThat(callback.hasReceivedProgress()).isFalse();
- // TODO: Because of b/130234145, consent dialog is not shown; so we get a timeout error.
- // When the bug is fixed, accept consent via UIAutomator and verify contents
- // of mBugreportFd.
- assertThat(callback.getErrorCode()).isEqualTo(
- BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
+ assertThat(mBugreportFile.length()).isGreaterThan(0L);
assertFdsAreClosed(mBugreportFd);
}
+ @LargeTest
@Test
public void normalFlow_interactive() throws Exception {
BugreportCallbackImpl callback = new BugreportCallbackImpl();
// interactive bugreport does not take screenshot
mBrm.startBugreport(mBugreportFd, null /*screenshotFd = null*/, interactive(),
mExecutor, callback);
-
+ shareConsentDialog(ConsentReply.ALLOW);
waitTillDoneOrTimeout(callback);
+
assertThat(callback.isDone()).isTrue();
// Interactive bugreports show progress updates.
assertThat(callback.hasReceivedProgress()).isTrue();
- assertThat(callback.getErrorCode()).isEqualTo(
- BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
+ assertThat(mBugreportFile.length()).isGreaterThan(0L);
assertFdsAreClosed(mBugreportFd);
}
+ @LargeTest
@Test
public void normalFlow_full() throws Exception {
BugreportCallbackImpl callback = new BugreportCallbackImpl();
mBrm.startBugreport(mBugreportFd, mScreenshotFd, full(), mExecutor, callback);
-
+ shareConsentDialog(ConsentReply.ALLOW);
waitTillDoneOrTimeout(callback);
+
assertThat(callback.isDone()).isTrue();
- assertThat(callback.getErrorCode()).isEqualTo(
- BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
- // bugreport and screenshot files should be empty when user consent timed out.
- assertThat(mBugreportFile.length()).isEqualTo(0);
- assertThat(mScreenshotFile.length()).isEqualTo(0);
+ // bugreport and screenshot files shouldn't be empty when user consents.
+ assertThat(mBugreportFile.length()).isGreaterThan(0L);
+ assertThat(mScreenshotFile.length()).isGreaterThan(0L);
assertFdsAreClosed(mBugreportFd, mScreenshotFd);
}
@@ -144,6 +158,8 @@ public class BugreportManagerTest {
// Start bugreport #1
BugreportCallbackImpl callback = new BugreportCallbackImpl();
mBrm.startBugreport(mBugreportFd, mScreenshotFd, wifi(), mExecutor, callback);
+ // TODO(b/162389762) Make sure the wait time is reasonable
+ shareConsentDialog(ConsentReply.ALLOW);
// Before #1 is done, try to start #2.
assertThat(callback.isDone()).isFalse();
@@ -375,4 +391,88 @@ public class BugreportManagerTest {
private static BugreportParams full() {
return new BugreportParams(BugreportParams.BUGREPORT_MODE_FULL);
}
+
+ /* Allow/deny the consent dialog to sharing bugreport data or check existence only. */
+ private enum ConsentReply {
+ ALLOW,
+ DENY,
+ TIMEOUT
+ }
+
+ /*
+ * Ensure the consent dialog is shown and take action according to <code>consentReply<code/>.
+ * It will fail if the dialog is not shown when <code>ignoreNotFound<code/> is false.
+ */
+ private void shareConsentDialog(@NonNull ConsentReply consentReply) throws Exception {
+ mTemporaryVmPolicy.permitIncorrectContextUse();
+ final UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+
+ // Unlock before finding/clicking an object.
+ device.wakeUp();
+ device.executeShellCommand("wm dismiss-keyguard");
+
+ final BySelector consentTitleObj = By.res("android", "alertTitle");
+ if (!device.wait(Until.hasObject(consentTitleObj), UIAUTOMATOR_TIMEOUT_MS)) {
+ fail("The consent dialog is not found");
+ }
+ if (consentReply.equals(ConsentReply.TIMEOUT)) {
+ return;
+ }
+ final BySelector selector;
+ if (consentReply.equals(ConsentReply.ALLOW)) {
+ selector = By.res("android", "button1");
+ Log.d(TAG, "Allow the consent dialog");
+ } else { // ConsentReply.DENY
+ selector = By.res("android", "button2");
+ Log.d(TAG, "Deny the consent dialog");
+ }
+ final UiObject2 btnObj = device.findObject(selector);
+ assertNotNull("The button of consent dialog is not found", btnObj);
+ btnObj.click();
+
+ Log.d(TAG, "Wait for the dialog to be dismissed");
+ assertTrue(device.wait(Until.gone(consentTitleObj), UIAUTOMATOR_TIMEOUT_MS));
+ }
+
+ /**
+ * A rule to change strict mode vm policy temporarily till test method finished.
+ *
+ * To permit the non-visual context usage in tests while taking bugreports need user consent,
+ * or UiAutomator/BugreportManager.DumpstateListener would run into error.
+ * UiDevice#findObject creates UiObject2, its Gesture object and ViewConfiguration and
+ * UiObject2#click need to know bounds. Both of them access to WindowManager internally without
+ * visual context comes from InstrumentationRegistry and violate the policy.
+ * Also <code>DumpstateListener<code/> violate the policy when onScreenshotTaken is called.
+ *
+ * TODO(b/161201609) Remove this class once violations fixed.
+ */
+ static class ExtendedStrictModeVmPolicy extends ExternalResource {
+ private boolean mWasVmPolicyChanged = false;
+ private StrictMode.VmPolicy mOldVmPolicy;
+
+ @Override
+ protected void after() {
+ restoreVmPolicyIfNeeded();
+ }
+
+ public void permitIncorrectContextUse() {
+ // Allow to call multiple times without losing old policy.
+ if (mOldVmPolicy == null) {
+ mOldVmPolicy = StrictMode.getVmPolicy();
+ }
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+ .detectAll()
+ .permitIncorrectContextUse()
+ .penaltyLog()
+ .build());
+ mWasVmPolicyChanged = true;
+ }
+
+ private void restoreVmPolicyIfNeeded() {
+ if (mWasVmPolicyChanged && mOldVmPolicy != null) {
+ StrictMode.setVmPolicy(mOldVmPolicy);
+ mOldVmPolicy = null;
+ }
+ }
+ }
}
diff --git a/core/tests/coretests/apks/install/res/values/strings.xml b/core/tests/coretests/apks/install/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install/res/values/strings.xml
+++ b/core/tests/coretests/apks/install/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml b/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml b/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml b/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml b/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml b/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml b/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/keyset/res/values/strings.xml b/core/tests/coretests/apks/keyset/res/values/strings.xml
index ff99ffa77b2a..d811ec29ef19 100644
--- a/core/tests/coretests/apks/keyset/res/values/strings.xml
+++ b/core/tests/coretests/apks/keyset/res/values/strings.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
<string name="keyset_perm_desc">keyset_perm_description</string>
<string name="keyset_perm_label">keyset_perm_label</string>
</resources>
diff --git a/core/tests/coretests/apks/version/res/values/strings.xml b/core/tests/coretests/apks/version/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/version/res/values/strings.xml
+++ b/core/tests/coretests/apks/version/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/apks/version_nosys/res/values/strings.xml b/core/tests/coretests/apks/version_nosys/res/values/strings.xml
index 3b8b3b1af9b5..984152fb5fa7 100644
--- a/core/tests/coretests/apks/version_nosys/res/values/strings.xml
+++ b/core/tests/coretests/apks/version_nosys/res/values/strings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="dummy">dummy</string>
+ <string name="placeholder">placeholder</string>
</resources>
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index af3660a6dab9..ae6e79a040f7 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
public class VintfObjectTest extends TestCase {
/**
- * Sanity check for {@link VintfObject#report VintfObject.report()}.
+ * Quick check for {@link VintfObject#report VintfObject.report()}.
*/
public void testReport() {
String[] xmls = VintfObject.report();
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 4cdfbb8ce27f..5711f98e3b75 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -415,6 +415,7 @@ key 583 ASSIST
key usage 0x0c0067 WINDOW
key usage 0x0c006F BRIGHTNESS_UP
key usage 0x0c0070 BRIGHTNESS_DOWN
+key usage 0x0c0173 MEDIA_AUDIO_TRACK
# Joystick and game controller axes.
# Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
diff --git a/data/keyboards/Vendor_2dc8_Product_6101.kl b/data/keyboards/Vendor_2dc8_Product_6101.kl
new file mode 100644
index 000000000000..ec9f5581b006
--- /dev/null
+++ b/data/keyboards/Vendor_2dc8_Product_6101.kl
@@ -0,0 +1,55 @@
+# 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.
+
+#
+# 8BitDo - SN30 Pro gamepad in Android (D-Input) mode
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Button labeled as "A" but should really produce keycode "B"
+key 304 BUTTON_B
+# Button labeled as "B" but should really produce keycode "A"
+key 305 BUTTON_A
+# Button labeled as "X" but should really produce keycode "Y"
+key 307 BUTTON_Y
+# Button labeled as "Y" but should really produce keycode "X"
+key 308 BUTTON_X
+
+key 310 BUTTON_L1
+key 312 BUTTON_L2
+key 311 BUTTON_R1
+key 313 BUTTON_R2
+
+# Button "Start" does not emit event when gamepad is in Android mode
+# Button "Home"
+key 306 BUTTON_MODE
+key 314 BUTTON_SELECT
+key 315 BUTTON_START
+
+key 317 BUTTON_THUMBL
+key 318 BUTTON_THUMBR
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+
+# Right Analog Stick
+axis 0x02 Z
+axis 0x05 RZ
+
+# Dpad
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 1da434496297..b3103fd516dd 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -23,6 +23,7 @@ import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
@@ -157,7 +158,7 @@ public class HardwareRenderer {
protected RenderNode mRootNode;
private boolean mOpaque = true;
private boolean mForceDark = false;
- private boolean mIsWideGamut = false;
+ private @ActivityInfo.ColorMode int mColorMode = ActivityInfo.COLOR_MODE_DEFAULT;
/**
* Creates a new instance of a HardwareRenderer. The HardwareRenderer will default
@@ -167,7 +168,7 @@ public class HardwareRenderer {
ProcessInitializer.sInstance.initDisplayInfo();
mRootNode = RenderNode.adopt(nCreateRootRenderNode());
mRootNode.setClipToBounds(false);
- mNativeProxy = nCreateProxy(!mOpaque, mIsWideGamut, mRootNode.mNativeRenderNode);
+ mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode);
if (mNativeProxy == 0) {
throw new OutOfMemoryError("Unable to create hardware renderer");
}
@@ -619,17 +620,17 @@ public class HardwareRenderer {
}
/**
- * Enable/disable wide gamut rendering on this renderer. Whether or not the actual rendering
- * will be wide gamut depends on the hardware support for such rendering.
+ * Sets the desired color mode on this renderer. Whether or not the actual rendering
+ * will use the requested colorMode depends on the hardware support for such rendering.
*
- * @param wideGamut true if this renderer should render in wide gamut, false if it should
- * render in sRGB
- * TODO: Figure out color...
+ * @param colorMode The @{@link ActivityInfo.ColorMode} to request
* @hide
*/
- public void setWideGamut(boolean wideGamut) {
- mIsWideGamut = wideGamut;
- nSetWideGamut(mNativeProxy, wideGamut);
+ public void setColorMode(@ActivityInfo.ColorMode int colorMode) {
+ if (mColorMode != colorMode) {
+ mColorMode = colorMode;
+ nSetColorMode(mNativeProxy, colorMode);
+ }
}
/**
@@ -804,11 +805,6 @@ public class HardwareRenderer {
nSetPictureCaptureCallback(mNativeProxy, callback);
}
- /** @hide */
- public boolean isWideGamut() {
- return mIsWideGamut;
- }
-
/** called by native */
static void invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback) {
Picture picture = new Picture(picturePtr);
@@ -1207,8 +1203,7 @@ public class HardwareRenderer {
private static native long nCreateRootRenderNode();
- private static native long nCreateProxy(boolean translucent, boolean isWideGamut,
- long rootRenderNode);
+ private static native long nCreateProxy(boolean translucent, long rootRenderNode);
private static native void nDeleteProxy(long nativeProxy);
@@ -1230,7 +1225,7 @@ public class HardwareRenderer {
private static native void nSetOpaque(long nativeProxy, boolean opaque);
- private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
+ private static native void nSetColorMode(long nativeProxy, int colorMode);
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index 338ece5afbc2..aeda2d923490 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -68,12 +68,15 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
private final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();
private final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();
- public DisplayImeController(IWindowManager wmService, DisplayController displayController,
+ protected DisplayImeController(IWindowManager wmService, DisplayController displayController,
Handler mainHandler, TransactionPool transactionPool) {
mHandler = mainHandler;
mWmService = wmService;
mTransactionPool = transactionPool;
mDisplayController = displayController;
+ }
+
+ protected void startMonitorDisplays() {
mDisplayController.addDisplayWindowListener(this);
}
@@ -490,4 +493,29 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
return IInputMethodManager.Stub.asInterface(
ServiceManager.getService(Context.INPUT_METHOD_SERVICE));
}
+
+ /** Builds {@link DisplayImeController} instance. */
+ public static class Builder {
+ private IWindowManager mWmService;
+ private DisplayController mDisplayController;
+ private Handler mHandler;
+ private TransactionPool mTransactionPool;
+
+ public Builder(IWindowManager wmService, DisplayController displayController,
+ Handler handler, TransactionPool transactionPool) {
+ mWmService = wmService;
+ mDisplayController = displayController;
+ mHandler = handler;
+ mTransactionPool = transactionPool;
+ }
+
+ /** Builds and initializes {@link DisplayImeController} instance. */
+ public DisplayImeController build() {
+ DisplayImeController displayImeController = new DisplayImeController(mWmService,
+ mDisplayController, mHandler, mTransactionPool);
+ // Separates startMonitorDisplays from constructor to prevent circular init issue.
+ displayImeController.startMonitorDisplays();
+ return displayImeController;
+ }
+ }
}
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 3893041b05d9..8ab7da5257ab 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -101,7 +101,7 @@ cc_library {
},
},
sanitize: {
- blacklist: "libandroidfw_blacklist.txt",
+ blocklist: "libandroidfw_blocklist.txt",
},
}
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index e351a46d633a..e10a7f3f5c61 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1717,6 +1717,10 @@ struct ResTable_overlayable_policy_header
// The overlay must be signed with the same signature as the actor declared for the target
// resource
ACTOR_SIGNATURE = 0x00000080,
+
+ // The overlay must be signed with the same signature as the reference package declared
+ // in the SystemConfig
+ CONFIG_SIGNATURE = 0x00000100,
};
using PolicyBitmask = uint32_t;
diff --git a/libs/androidfw/libandroidfw_blacklist.txt b/libs/androidfw/libandroidfw_blocklist.txt
index dd17e4d5b1e8..dd17e4d5b1e8 100644
--- a/libs/androidfw/libandroidfw_blacklist.txt
+++ b/libs/androidfw/libandroidfw_blocklist.txt
diff --git a/libs/hwui/ColorMode.h b/libs/hwui/ColorMode.h
new file mode 100644
index 000000000000..6d387f9ef43d
--- /dev/null
+++ b/libs/hwui/ColorMode.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+namespace android::uirenderer {
+
+// Must match the constants in ActivityInfo.java
+enum class ColorMode {
+ // SRGB means HWUI will produce buffer in SRGB color space.
+ Default = 0,
+ // WideColorGamut selects the most optimal colorspace & format for the device's display
+ // Most commonly DisplayP3 + RGBA_8888 currently.
+ WideColorGamut = 1,
+ // HDR Rec2020 + F16
+ Hdr = 2,
+ // HDR Rec2020 + 1010102
+ Hdr10 = 3,
+};
+
+} // namespace android::uirenderer
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
index b933813550d4..12e2e8135278 100644
--- a/libs/hwui/apex/jni_runtime.cpp
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -16,14 +16,14 @@
#include "android/graphics/jni_runtime.h"
-#include <android/log.h>
-#include <nativehelper/JNIHelp.h>
-#include <sys/cdefs.h>
-
#include <EGL/egl.h>
#include <GraphicsJNI.h>
#include <Properties.h>
#include <SkGraphics.h>
+#include <android/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <sys/cdefs.h>
+#include <vulkan/vulkan.h>
#undef LOG_TAG
#define LOG_TAG "AndroidGraphicsJNI"
@@ -172,6 +172,11 @@ using android::uirenderer::RenderPipelineType;
void zygote_preload_graphics() {
if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) {
+ // Preload GL driver if HWUI renders with GL backend.
eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ } else {
+ // Preload Vulkan driver if HWUI renders with Vulkan backend.
+ uint32_t apiVersion;
+ vkEnumerateInstanceVersion(&apiVersion);
}
-} \ No newline at end of file
+}
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 42743db3061c..7d6875f59d17 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -143,11 +143,10 @@ static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, job
}
static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
- jboolean translucent, jboolean isWideGamut, jlong rootRenderNodePtr) {
+ jboolean translucent, jlong rootRenderNodePtr) {
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
ContextFactoryImpl factory(rootRenderNode);
RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory);
- proxy->setWideGamut(isWideGamut);
return (jlong) proxy;
}
@@ -218,10 +217,10 @@ static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
proxy->setOpaque(opaque);
}
-static void android_view_ThreadedRenderer_setWideGamut(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jboolean wideGamut) {
+static void android_view_ThreadedRenderer_setColorMode(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jint colorMode) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->setWideGamut(wideGamut);
+ proxy->setColorMode(static_cast<ColorMode>(colorMode));
}
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
@@ -659,7 +658,7 @@ static const JNINativeMethod gMethods[] = {
(void*)android_view_ThreadedRenderer_setProcessStatsBuffer},
{"nGetRenderThreadTid", "(J)I", (void*)android_view_ThreadedRenderer_getRenderThreadTid},
{"nCreateRootRenderNode", "()J", (void*)android_view_ThreadedRenderer_createRootRenderNode},
- {"nCreateProxy", "(ZZJ)J", (void*)android_view_ThreadedRenderer_createProxy},
+ {"nCreateProxy", "(ZJ)J", (void*)android_view_ThreadedRenderer_createProxy},
{"nDeleteProxy", "(J)V", (void*)android_view_ThreadedRenderer_deleteProxy},
{"nLoadSystemProperties", "(J)Z",
(void*)android_view_ThreadedRenderer_loadSystemProperties},
@@ -671,7 +670,7 @@ static const JNINativeMethod gMethods[] = {
{"nSetLightAlpha", "(JFF)V", (void*)android_view_ThreadedRenderer_setLightAlpha},
{"nSetLightGeometry", "(JFFFF)V", (void*)android_view_ThreadedRenderer_setLightGeometry},
{"nSetOpaque", "(JZ)V", (void*)android_view_ThreadedRenderer_setOpaque},
- {"nSetWideGamut", "(JZ)V", (void*)android_view_ThreadedRenderer_setWideGamut},
+ {"nSetColorMode", "(JI)V", (void*)android_view_ThreadedRenderer_setColorMode},
{"nSyncAndDrawFrame", "(J[JI)I", (void*)android_view_ThreadedRenderer_syncAndDrawFrame},
{"nDestroy", "(JJ)V", (void*)android_view_ThreadedRenderer_destroy},
{"nRegisterAnimatingRenderNode", "(JJ)V",
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 24a6228242a5..389fe7eed7c7 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -87,6 +87,8 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
// Note: The default preference of pixel format is RGBA_8888, when other
// pixel format is available, we should branch out and do more check.
fboInfo.fFormat = GL_RGBA8;
+ } else if (colorType == kRGBA_1010102_SkColorType) {
+ fboInfo.fFormat = GL_RGB10_A2;
} else {
LOG_ALWAYS_FATAL("Unsupported color type.");
}
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 89a1c713ef62..6dd36981e8aa 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -35,6 +35,7 @@
#include "VectorDrawable.h"
#include "thread/CommonPool.h"
#include "tools/SkSharingProc.h"
+#include "utils/Color.h"
#include "utils/String8.h"
#include "utils/TraceUtils.h"
@@ -587,14 +588,23 @@ void SkiaPipeline::dumpResourceCacheUsage() const {
void SkiaPipeline::setSurfaceColorProperties(ColorMode colorMode) {
mColorMode = colorMode;
- if (colorMode == ColorMode::SRGB) {
- mSurfaceColorType = SkColorType::kN32_SkColorType;
- mSurfaceColorSpace = SkColorSpace::MakeSRGB();
- } else if (colorMode == ColorMode::WideColorGamut) {
- mSurfaceColorType = DeviceInfo::get()->getWideColorType();
- mSurfaceColorSpace = DeviceInfo::get()->getWideColorSpace();
- } else {
- LOG_ALWAYS_FATAL("Unreachable: unsupported color mode.");
+ switch (colorMode) {
+ case ColorMode::Default:
+ mSurfaceColorType = SkColorType::kN32_SkColorType;
+ mSurfaceColorSpace = SkColorSpace::MakeSRGB();
+ break;
+ case ColorMode::WideColorGamut:
+ mSurfaceColorType = DeviceInfo::get()->getWideColorType();
+ mSurfaceColorSpace = DeviceInfo::get()->getWideColorSpace();
+ break;
+ case ColorMode::Hdr:
+ mSurfaceColorType = SkColorType::kRGBA_F16_SkColorType;
+ mSurfaceColorSpace = SkColorSpace::MakeRGB(GetPQSkTransferFunction(), SkNamedGamut::kRec2020);
+ break;
+ case ColorMode::Hdr10:
+ mSurfaceColorType = SkColorType::kRGBA_1010102_SkColorType;
+ mSurfaceColorSpace = SkColorSpace::MakeRGB(GetPQSkTransferFunction(), SkNamedGamut::kRec2020);
+ break;
}
}
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 8341164edc19..100bfb6b159a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -50,7 +50,7 @@ public:
bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
ErrorHandler* errorHandler) override;
- void setSurfaceColorProperties(renderthread::ColorMode colorMode) override;
+ void setSurfaceColorProperties(ColorMode colorMode) override;
SkColorType getSurfaceColorType() const override { return mSurfaceColorType; }
sk_sp<SkColorSpace> getSurfaceColorSpace() override { return mSurfaceColorSpace; }
@@ -76,7 +76,7 @@ protected:
renderthread::RenderThread& mRenderThread;
- renderthread::ColorMode mColorMode = renderthread::ColorMode::SRGB;
+ ColorMode mColorMode = ColorMode::Default;
SkColorType mSurfaceColorType;
sk_sp<SkColorSpace> mSurfaceColorSpace;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a362bd220936..13d544c68e95 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -174,7 +174,10 @@ void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
} else {
mNativeSurface = nullptr;
}
+ setupPipelineSurface();
+}
+void CanvasContext::setupPipelineSurface() {
bool hasSurface = mRenderPipeline->setSurface(
mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);
@@ -184,7 +187,7 @@ void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
mFrameNumber = -1;
- if (window != nullptr && hasSurface) {
+ if (mNativeSurface != nullptr && hasSurface) {
mHaveNewSurface = true;
mSwapHistory.clear();
// Enable frame stats after the surface has been bound to the appropriate graphics API.
@@ -239,9 +242,9 @@ void CanvasContext::setOpaque(bool opaque) {
mOpaque = opaque;
}
-void CanvasContext::setWideGamut(bool wideGamut) {
- ColorMode colorMode = wideGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
- mRenderPipeline->setSurfaceColorProperties(colorMode);
+void CanvasContext::setColorMode(ColorMode mode) {
+ mRenderPipeline->setSurfaceColorProperties(mode);
+ setupPipelineSurface();
}
bool CanvasContext::makeCurrent() {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 0306eeccc5d4..cba710f01063 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -30,6 +30,7 @@
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
#include "utils/RingBuffer.h"
+#include "ColorMode.h"
#include <SkBitmap.h>
#include <SkRect.h>
@@ -119,7 +120,7 @@ public:
void setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
void setLightGeometry(const Vector3& lightCenter, float lightRadius);
void setOpaque(bool opaque);
- void setWideGamut(bool wideGamut);
+ void setColorMode(ColorMode mode);
bool makeCurrent();
void prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued, RenderNode* target);
void draw();
@@ -211,6 +212,7 @@ private:
bool isSwapChainStuffed();
bool surfaceRequiresRedraw();
void setPresentTime();
+ void setupPipelineSurface();
SkRect computeDirtyRect(const Frame& frame, SkRect* dirty);
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index c7013531c07f..2a8aa8c3e5b7 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -76,6 +76,7 @@ static struct {
bool glColorSpace = false;
bool scRGB = false;
bool displayP3 = false;
+ bool hdr = false;
bool contextPriority = false;
bool surfacelessContext = false;
bool nativeFenceSync = false;
@@ -86,7 +87,8 @@ static struct {
EglManager::EglManager()
: mEglDisplay(EGL_NO_DISPLAY)
, mEglConfig(nullptr)
- , mEglConfigWideGamut(nullptr)
+ , mEglConfigF16(nullptr)
+ , mEglConfig1010102(nullptr)
, mEglContext(EGL_NO_CONTEXT)
, mPBufferSurface(EGL_NO_SURFACE)
, mCurrentSurface(EGL_NO_SURFACE)
@@ -143,8 +145,7 @@ void EglManager::initialize() {
} else {
LOG_ALWAYS_FATAL("Unsupported wide color space.");
}
- mHasWideColorGamutSupport = EglExtensions.glColorSpace && hasWideColorSpaceExtension &&
- mEglConfigWideGamut != EGL_NO_CONFIG_KHR;
+ mHasWideColorGamutSupport = EglExtensions.glColorSpace && hasWideColorSpaceExtension;
}
EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavior swapBehavior) {
@@ -177,6 +178,35 @@ EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavi
return config;
}
+EGLConfig EglManager::load1010102Config(EGLDisplay display, SwapBehavior swapBehavior) {
+ EGLint eglSwapBehavior =
+ (swapBehavior == SwapBehavior::Preserved) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
+ // If we reached this point, we have a valid swap behavior
+ EGLint attribs[] = {EGL_RENDERABLE_TYPE,
+ EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE,
+ 10,
+ EGL_GREEN_SIZE,
+ 10,
+ EGL_BLUE_SIZE,
+ 10,
+ EGL_ALPHA_SIZE,
+ 2,
+ EGL_DEPTH_SIZE,
+ 0,
+ EGL_STENCIL_SIZE,
+ STENCIL_BUFFER_SIZE,
+ EGL_SURFACE_TYPE,
+ EGL_WINDOW_BIT | eglSwapBehavior,
+ EGL_NONE};
+ EGLConfig config = EGL_NO_CONFIG_KHR;
+ EGLint numConfigs = 1;
+ if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
+ return EGL_NO_CONFIG_KHR;
+ }
+ return config;
+}
+
EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavior) {
EGLint eglSwapBehavior =
(swapBehavior == SwapBehavior::Preserved) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
@@ -230,6 +260,7 @@ void EglManager::initExtensions() {
EglExtensions.pixelFormatFloat = extensions.has("EGL_EXT_pixel_format_float");
EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough");
+ EglExtensions.hdr = extensions.has("EGL_EXT_gl_colorspace_bt2020_pq");
EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync");
@@ -260,18 +291,20 @@ void EglManager::loadConfigs() {
LOG_ALWAYS_FATAL("Failed to choose config, error = %s", eglErrorString());
}
}
- SkColorType wideColorType = DeviceInfo::get()->getWideColorType();
// When we reach this point, we have a valid swap behavior
- if (wideColorType == SkColorType::kRGBA_F16_SkColorType && EglExtensions.pixelFormatFloat) {
- mEglConfigWideGamut = loadFP16Config(mEglDisplay, mSwapBehavior);
- if (mEglConfigWideGamut == EGL_NO_CONFIG_KHR) {
+ if (EglExtensions.pixelFormatFloat) {
+ mEglConfigF16 = loadFP16Config(mEglDisplay, mSwapBehavior);
+ if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
eglErrorString());
EglExtensions.pixelFormatFloat = false;
}
- } else if (wideColorType == SkColorType::kN32_SkColorType) {
- mEglConfigWideGamut = load8BitsConfig(mEglDisplay, mSwapBehavior);
+ }
+ mEglConfig1010102 = load1010102Config(mEglDisplay, mSwapBehavior);
+ if (mEglConfig1010102 == EGL_NO_CONFIG_KHR) {
+ ALOGW("Failed to initialize 101010-2 format, error = %s",
+ eglErrorString());
}
}
@@ -311,8 +344,9 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,
sk_sp<SkColorSpace> colorSpace) {
LOG_ALWAYS_FATAL_IF(!hasEglContext(), "Not initialized");
- bool wideColorGamut = colorMode == ColorMode::WideColorGamut && mHasWideColorGamutSupport &&
- EglExtensions.noConfigContext;
+ if (!mHasWideColorGamutSupport || !EglExtensions.noConfigContext) {
+ colorMode = ColorMode::Default;
+ }
// The color space we want to use depends on whether linear blending is turned
// on and whether the app has requested wide color gamut rendering. When wide
@@ -338,26 +372,47 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,
// list is considered empty if the first entry is EGL_NONE
EGLint attribs[] = {EGL_NONE, EGL_NONE, EGL_NONE};
+ EGLConfig config = mEglConfig;
+ if (DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType) {
+ if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
+ colorMode = ColorMode::Default;
+ } else {
+ config = mEglConfigF16;
+ }
+ }
if (EglExtensions.glColorSpace) {
attribs[0] = EGL_GL_COLORSPACE_KHR;
- if (wideColorGamut) {
- skcms_Matrix3x3 colorGamut;
- LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
- "Could not get gamut matrix from color space");
- if (memcmp(&colorGamut, &SkNamedGamut::kDisplayP3, sizeof(colorGamut)) == 0) {
- attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
- } else if (memcmp(&colorGamut, &SkNamedGamut::kSRGB, sizeof(colorGamut)) == 0) {
- attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
- } else {
- LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
+ switch (colorMode) {
+ case ColorMode::Default:
+ attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+ break;
+ case ColorMode::WideColorGamut: {
+ skcms_Matrix3x3 colorGamut;
+ LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
+ "Could not get gamut matrix from color space");
+ if (memcmp(&colorGamut, &SkNamedGamut::kDisplayP3, sizeof(colorGamut)) == 0) {
+ attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
+ } else if (memcmp(&colorGamut, &SkNamedGamut::kSRGB, sizeof(colorGamut)) == 0) {
+ attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
+ } else if (memcmp(&colorGamut, &SkNamedGamut::kRec2020, sizeof(colorGamut)) == 0) {
+ attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+ } else {
+ LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
+ }
+ break;
}
- } else {
- attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+ case ColorMode::Hdr:
+ config = mEglConfigF16;
+ attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+ break;
+ case ColorMode::Hdr10:
+ config = mEglConfig1010102;
+ attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+ break;
}
}
- EGLSurface surface = eglCreateWindowSurface(
- mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
+ EGLSurface surface = eglCreateWindowSurface(mEglDisplay, config, window, attribs);
if (surface == EGL_NO_SURFACE) {
return Error<EGLint>{eglGetError()};
}
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index f67fb31db951..69f3ed014c53 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -88,6 +88,7 @@ private:
static EGLConfig load8BitsConfig(EGLDisplay display, SwapBehavior swapBehavior);
static EGLConfig loadFP16Config(EGLDisplay display, SwapBehavior swapBehavior);
+ static EGLConfig load1010102Config(EGLDisplay display, SwapBehavior swapBehavior);
void initExtensions();
void createPBufferSurface();
@@ -97,7 +98,8 @@ private:
EGLDisplay mEglDisplay;
EGLConfig mEglConfig;
- EGLConfig mEglConfigWideGamut;
+ EGLConfig mEglConfigF16;
+ EGLConfig mEglConfig1010102;
EGLContext mEglContext;
EGLSurface mPBufferSurface;
EGLSurface mCurrentSurface;
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index c3c22869a42f..a04738d6a6f0 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -22,6 +22,7 @@
#include "Lighting.h"
#include "SwapBehavior.h"
#include "hwui/Bitmap.h"
+#include "ColorMode.h"
#include <SkRect.h>
#include <utils/RefBase.h>
@@ -42,16 +43,6 @@ namespace renderthread {
enum class MakeCurrentResult { AlreadyCurrent, Failed, Succeeded };
-enum class ColorMode {
- // SRGB means HWUI will produce buffer in SRGB color space.
- SRGB,
- // WideColorGamut means HWUI would support rendering scRGB non-linear into
- // a signed buffer with enough range to support the wide color gamut of the
- // display.
- WideColorGamut,
- // Hdr
-};
-
class Frame;
class IRenderPipeline {
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index b764f74bf116..aad0cca80cdc 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -109,8 +109,8 @@ void RenderProxy::setOpaque(bool opaque) {
mRenderThread.queue().post([=]() { mContext->setOpaque(opaque); });
}
-void RenderProxy::setWideGamut(bool wideGamut) {
- mRenderThread.queue().post([=]() { mContext->setWideGamut(wideGamut); });
+void RenderProxy::setColorMode(ColorMode mode) {
+ mRenderThread.queue().post([=]() { mContext->setColorMode(mode); });
}
int64_t* RenderProxy::frameInfo() {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 16eabadc064c..33dabc9895b1 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -24,6 +24,7 @@
#include "../FrameMetricsObserver.h"
#include "../IContextFactory.h"
+#include "ColorMode.h"
#include "DrawFrameTask.h"
#include "SwapBehavior.h"
#include "hwui/Bitmap.h"
@@ -77,7 +78,7 @@ public:
void setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
void setLightGeometry(const Vector3& lightCenter, float lightRadius);
void setOpaque(bool opaque);
- void setWideGamut(bool wideGamut);
+ void setColorMode(ColorMode mode);
int64_t* frameInfo();
int syncAndDrawFrame();
void destroy();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index bea6121905a5..565fb61c8994 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -162,7 +162,6 @@ void RenderThread::initializeChoreographer() {
}
void RenderThread::initThreadLocals() {
- HardwareBitmapUploader::initialize();
setupFrameInterval();
initializeChoreographer();
mEglManager = new EglManager();
@@ -391,12 +390,10 @@ void RenderThread::preload() {
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); });
eglInitThread.detach();
+ } else {
+ requireVkContext();
}
- // TODO: uncomment only after http://b/135536511 is fixed.
- // else {
- // uint32_t apiVersion;
- // vkEnumerateInstanceVersion(&apiVersion);
- //}
+ HardwareBitmapUploader::initialize();
}
} /* namespace renderthread */
diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp
index ca1bf690cfd0..eff34a83af1b 100644
--- a/libs/hwui/utils/Color.cpp
+++ b/libs/hwui/utils/Color.cpp
@@ -344,5 +344,27 @@ SkColor LabToSRGB(const Lab& lab, SkAlpha alpha) {
static_cast<uint8_t>(rgb.b * 255));
}
+// Note that SkColorSpace doesn't have the notion of an unspecified SDR white
+// level.
+static constexpr float kDefaultSDRWhiteLevel = 150.f;
+
+skcms_TransferFunction GetPQSkTransferFunction(float sdr_white_level) {
+ if (sdr_white_level <= 0.f) {
+ sdr_white_level = kDefaultSDRWhiteLevel;
+ }
+ // The generic PQ transfer function produces normalized luminance values i.e.
+ // the range 0-1 represents 0-10000 nits for the reference display, but we
+ // want to map 1.0 to |sdr_white_level| nits so we need to scale accordingly.
+ const double w = 10000. / sdr_white_level;
+ // Distribute scaling factor W by scaling A and B with X ^ (1/F):
+ // ((A + Bx^C) / (D + Ex^C))^F * W = ((A + Bx^C) / (D + Ex^C) * W^(1/F))^F
+ // See https://crbug.com/1058580#c32 for discussion.
+ skcms_TransferFunction fn = SkNamedTransferFn::kPQ;
+ const double ws = pow(w, 1. / fn.f);
+ fn.a = ws * fn.a;
+ fn.b = ws * fn.b;
+ return fn;
+}
+
} // namespace uirenderer
} // namespace android
diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h
index 71ed68371a9a..1654072fd264 100644
--- a/libs/hwui/utils/Color.h
+++ b/libs/hwui/utils/Color.h
@@ -126,6 +126,7 @@ struct Lab {
Lab sRGBToLab(SkColor color);
SkColor LabToSRGB(const Lab& lab, SkAlpha alpha);
+skcms_TransferFunction GetPQSkTransferFunction(float sdr_white_level = 0.f);
} /* namespace uirenderer */
} /* namespace android */
diff --git a/location/java/android/location/GnssAntennaInfo.java b/location/java/android/location/GnssAntennaInfo.java
index b2f9a0f41b7e..23977f18f749 100644
--- a/location/java/android/location/GnssAntennaInfo.java
+++ b/location/java/android/location/GnssAntennaInfo.java
@@ -53,7 +53,7 @@ public final class GnssAntennaInfo implements Parcelable {
* Class containing information about the antenna phase center offset (PCO). PCO is defined with
* respect to the origin of the Android sensor coordinate system, e.g., center of primary screen
* for mobiles - see sensor or form factor documents for details. Uncertainties are reported
- * to 1-sigma.
+ * to 1-sigma.
*/
public static final class PhaseCenterOffset implements Parcelable {
private final double mOffsetXMm;
@@ -95,31 +95,55 @@ public final class GnssAntennaInfo implements Parcelable {
}
};
+ /**
+ * Returns the x-axis offset of the phase center from the origin of the Android sensor
+ * coordinate system, in millimeters.
+ */
@FloatRange()
public double getXOffsetMm() {
return mOffsetXMm;
}
+ /**
+ * Returns the 1-sigma uncertainty of the x-axis offset of the phase center from the origin
+ * of the Android sensor coordinate system, in millimeters.
+ */
@FloatRange()
public double getXOffsetUncertaintyMm() {
return mOffsetXUncertaintyMm;
}
+ /**
+ * Returns the y-axis offset of the phase center from the origin of the Android sensor
+ * coordinate system, in millimeters.
+ */
@FloatRange()
public double getYOffsetMm() {
return mOffsetYMm;
}
+ /**
+ * Returns the 1-sigma uncertainty of the y-axis offset of the phase center from the origin
+ * of the Android sensor coordinate system, in millimeters.
+ */
@FloatRange()
public double getYOffsetUncertaintyMm() {
return mOffsetYUncertaintyMm;
}
+ /**
+ * Returns the z-axis offset of the phase center from the origin of the Android sensor
+ * coordinate system, in millimeters.
+ */
@FloatRange()
public double getZOffsetMm() {
return mOffsetZMm;
}
+ /**
+ * Returns the 1-sigma uncertainty of the z-axis offset of the phase center from the origin
+ * of the Android sensor coordinate system, in millimeters.
+ */
@FloatRange()
public double getZOffsetUncertaintyMm() {
return mOffsetZUncertaintyMm;
@@ -165,7 +189,7 @@ public final class GnssAntennaInfo implements Parcelable {
* at 180 degrees. They are separated by deltaPhi, the regular spacing between zenith angles,
* i.e., deltaPhi = 180 / (number of columns - 1).
*/
- public static final class SphericalCorrections implements Parcelable{
+ public static final class SphericalCorrections implements Parcelable {
private final double[][] mCorrections;
private final double[][] mCorrectionUncertainties;
private final double mDeltaTheta;
@@ -296,10 +320,10 @@ public final class GnssAntennaInfo implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mNumRows);
dest.writeInt(mNumColumns);
- for (double[] row: mCorrections) {
+ for (double[] row : mCorrections) {
dest.writeDoubleArray(row);
}
- for (double[] row: mCorrectionUncertainties) {
+ for (double[] row : mCorrectionUncertainties) {
dest.writeDoubleArray(row);
}
}
@@ -340,6 +364,7 @@ public final class GnssAntennaInfo implements Parcelable {
/**
* Set antenna carrier frequency (MHz).
+ *
* @param carrierFrequencyMHz antenna carrier frequency (MHz)
* @return Builder builder object
*/
@@ -351,6 +376,7 @@ public final class GnssAntennaInfo implements Parcelable {
/**
* Set antenna phase center offset.
+ *
* @param phaseCenterOffset phase center offset object
* @return Builder builder object
*/
@@ -362,6 +388,7 @@ public final class GnssAntennaInfo implements Parcelable {
/**
* Set phase center variation corrections.
+ *
* @param phaseCenterVariationCorrections phase center variation corrections object
* @return Builder builder object
*/
@@ -374,6 +401,7 @@ public final class GnssAntennaInfo implements Parcelable {
/**
* Set signal gain corrections.
+ *
* @param signalGainCorrections signal gain corrections object
* @return Builder builder object
*/
@@ -386,6 +414,7 @@ public final class GnssAntennaInfo implements Parcelable {
/**
* Build GnssAntennaInfo object.
+ *
* @return instance of GnssAntennaInfo
*/
@NonNull
@@ -400,47 +429,65 @@ public final class GnssAntennaInfo implements Parcelable {
return mCarrierFrequencyMHz;
}
+ /**
+ * Returns a {@link PhaseCenterOffset} object encapsulating the phase center offset and
+ * corresponding uncertainties in millimeters.
+ *
+ * @return {@link PhaseCenterOffset}
+ */
@NonNull
public PhaseCenterOffset getPhaseCenterOffset() {
return mPhaseCenterOffset;
}
+ /**
+ * Returns a {@link SphericalCorrections} object encapsulating the phase center variation
+ * corrections and corresponding uncertainties in millimeters.
+ *
+ * @return phase center variation corrections as {@link SphericalCorrections}
+ */
@Nullable
public SphericalCorrections getPhaseCenterVariationCorrections() {
return mPhaseCenterVariationCorrections;
}
+ /**
+ * Returns a {@link SphericalCorrections} object encapsulating the signal gain
+ * corrections and corresponding uncertainties in dBi.
+ *
+ * @return signal gain corrections as {@link SphericalCorrections}
+ */
@Nullable
public SphericalCorrections getSignalGainCorrections() {
return mSignalGainCorrections;
}
- public static final @android.annotation.NonNull
- Creator<GnssAntennaInfo> CREATOR = new Creator<GnssAntennaInfo>() {
- @Override
- public GnssAntennaInfo createFromParcel(Parcel in) {
- double carrierFrequencyMHz = in.readDouble();
-
- ClassLoader classLoader = getClass().getClassLoader();
- PhaseCenterOffset phaseCenterOffset =
- in.readParcelable(classLoader);
- SphericalCorrections phaseCenterVariationCorrections =
- in.readParcelable(classLoader);
- SphericalCorrections signalGainCorrections =
- in.readParcelable(classLoader);
-
- return new GnssAntennaInfo(
- carrierFrequencyMHz,
- phaseCenterOffset,
- phaseCenterVariationCorrections,
- signalGainCorrections);
- }
-
- @Override
- public GnssAntennaInfo[] newArray(int size) {
- return new GnssAntennaInfo[size];
- }
- };
+ public static final @android.annotation.NonNull Creator<GnssAntennaInfo> CREATOR =
+ new Creator<GnssAntennaInfo>() {
+ @Override
+ public GnssAntennaInfo createFromParcel(Parcel in) {
+ double carrierFrequencyMHz = in.readDouble();
+
+ ClassLoader classLoader = getClass().getClassLoader();
+ PhaseCenterOffset phaseCenterOffset =
+ in.readParcelable(classLoader);
+ SphericalCorrections phaseCenterVariationCorrections =
+ in.readParcelable(classLoader);
+ SphericalCorrections signalGainCorrections =
+ in.readParcelable(classLoader);
+
+ return new GnssAntennaInfo(
+ carrierFrequencyMHz,
+ phaseCenterOffset,
+ phaseCenterVariationCorrections,
+ signalGainCorrections);
+ }
+
+ @Override
+ public GnssAntennaInfo[] newArray(int size) {
+ return new GnssAntennaInfo[size];
+ }
+ };
@Override
public int describeContents() {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3ac71b2cff1d..408f34be6b65 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -564,6 +564,7 @@ public class AudioManager {
* request is from a hardware key press. (e.g. {@link MediaController}).
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int FLAG_FROM_KEY = 1 << 12;
// The iterator of TreeMap#entrySet() returns the entries in ascending key order.
@@ -3801,7 +3802,7 @@ public class AudioManager {
final IAudioService service = getService();
try {
service.unregisterAudioPolicyAsync(policy.cb());
- policy.setRegistration(null);
+ policy.reset();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3823,7 +3824,7 @@ public class AudioManager {
try {
policy.invalidateCaptorsAndInjectors();
service.unregisterAudioPolicy(policy.cb());
- policy.setRegistration(null);
+ policy.reset();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4600,36 +4601,41 @@ public class AudioManager {
/**
* @hide
* Volume behavior for an audio device that has no particular volume behavior set. Invalid as
- * an argument to {@link #setDeviceVolumeBehavior(int, String, int)}.
+ * an argument to {@link #setDeviceVolumeBehavior(AudioDeviceAttributes, int)} and should not
+ * be returned by {@link #getDeviceVolumeBehavior(AudioDeviceAttributes)}.
*/
public static final int DEVICE_VOLUME_BEHAVIOR_UNSET = -1;
/**
* @hide
* Volume behavior for an audio device where a software attenuation is applied
- * @see #setDeviceVolumeBehavior(int, String, int)
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
*/
+ @SystemApi
public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
/**
* @hide
* Volume behavior for an audio device where the volume is always set to provide no attenuation
* nor gain (e.g. unit gain).
- * @see #setDeviceVolumeBehavior(int, String, int)
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
*/
+ @SystemApi
public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
/**
* @hide
* Volume behavior for an audio device where the volume is either set to muted, or to provide
* no attenuation nor gain (e.g. unit gain).
- * @see #setDeviceVolumeBehavior(int, String, int)
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
*/
+ @SystemApi
public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
/**
* @hide
* Volume behavior for an audio device where no software attenuation is applied, and
* the volume is kept synchronized between the host and the device itself through a
* device-specific protocol such as BT AVRCP.
- * @see #setDeviceVolumeBehavior(int, String, int)
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
*/
+ @SystemApi
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
/**
* @hide
@@ -4638,8 +4644,9 @@ public class AudioManager {
* device-specific protocol (such as for hearing aids), based on the audio mode (e.g.
* normal vs in phone call).
* @see #setMode(int)
- * @see #setDeviceVolumeBehavior(int, String, int)
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
*/
+ @SystemApi
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
/** @hide */
@@ -4686,27 +4693,15 @@ public class AudioManager {
/**
* @hide
* Sets the volume behavior for an audio output device.
- * @param deviceType the type of audio device to be affected. Currently only supports
- * {@link AudioDeviceInfo#TYPE_HDMI}, {@link AudioDeviceInfo#TYPE_HDMI_ARC},
- * {@link AudioDeviceInfo#TYPE_LINE_DIGITAL} and {@link AudioDeviceInfo#TYPE_AUX_LINE}
- * @param deviceAddress the address of the device, if any
- * @param deviceVolumeBehavior one of the device behaviors
- */
- @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public void setDeviceVolumeBehavior(int deviceType, @Nullable String deviceAddress,
- @DeviceVolumeBehavior int deviceVolumeBehavior) {
- setDeviceVolumeBehavior(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
- deviceType, deviceAddress), deviceVolumeBehavior);
- }
-
- /**
- * @hide
- * Sets the volume behavior for an audio output device.
- * @param device the device to be affected. Currently only supports devices of type
- * {@link AudioDeviceInfo#TYPE_HDMI}, {@link AudioDeviceInfo#TYPE_HDMI_ARC},
- * {@link AudioDeviceInfo#TYPE_LINE_DIGITAL} and {@link AudioDeviceInfo#TYPE_AUX_LINE}
+ * @see #DEVICE_VOLUME_BEHAVIOR_VARIABLE
+ * @see #DEVICE_VOLUME_BEHAVIOR_FULL
+ * @see #DEVICE_VOLUME_BEHAVIOR_FIXED
+ * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE
+ * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
+ * @param device the device to be affected
* @param deviceVolumeBehavior one of the device behaviors
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
@DeviceVolumeBehavior int deviceVolumeBehavior) {
@@ -4725,29 +4720,14 @@ public class AudioManager {
/**
* @hide
- * Returns the volume device behavior for the given device type and address
- * @param deviceType an audio output device type, as defined in {@link AudioDeviceInfo}
- * @param deviceAddress the address of the audio device, if any.
- * @return the volume behavior for the device
- */
- @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @DeviceVolumeBehaviorState int getDeviceVolumeBehavior(int deviceType,
- @Nullable String deviceAddress) {
- // verify arguments
- AudioDeviceInfo.enforceValidAudioDeviceTypeOut(deviceType);
- return getDeviceVolumeBehavior(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
- deviceType, deviceAddress));
- }
-
- /**
- * @hide
* Returns the volume device behavior for the given audio device
* @param device the audio device
* @return the volume behavior for the device
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @DeviceVolumeBehaviorState int getDeviceVolumeBehavior(
- @NonNull AudioDeviceAttributes device) {
+ public @DeviceVolumeBehavior
+ int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
// verify arguments (validity of device type is enforced in server)
Objects.requireNonNull(device);
// communicate with service
@@ -6200,6 +6180,24 @@ public class AudioManager {
}
}
+
+ /**
+ * Retrieves the Hardware A/V synchronization ID corresponding to the given audio session ID.
+ * For more details on Hardware A/V synchronization please refer to
+ * <a href="https://source.android.com/devices/tv/multimedia-tunneling/">
+ * media tunneling documentation</a>.
+ * @param sessionId the audio session ID for which the HW A/V sync ID is retrieved.
+ * @return the HW A/V sync ID for this audio session (an integer different from 0).
+ * @throws UnsupportedOperationException if HW A/V synchronization is not supported.
+ */
+ public int getAudioHwSyncForSession(int sessionId) {
+ int hwSyncId = AudioSystem.getAudioHwSyncForSession(sessionId);
+ if (hwSyncId == AudioSystem.AUDIO_HW_SYNC_INVALID) {
+ throw new UnsupportedOperationException("HW A/V synchronization is not supported.");
+ }
+ return hwSyncId;
+ }
+
//---------------------------------------------------------
// Inner classes
//--------------------
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 4d26b8d3f7af..c9cdbb0ed277 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -487,6 +487,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
}
}
+ /** @hide */
+ public AudioAttributes getAudioAttributes() {
+ return mAudioAttributes;
+ }
+
/**
* Builder class for {@link AudioRecord} objects.
* Use this class to configure and create an <code>AudioRecord</code> instance. By setting the
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index a80600c359a4..57e8e438d592 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -70,6 +70,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
+import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
@@ -2095,7 +2096,10 @@ public class ExifInterface {
try {
// Move the original file to temporary file.
if (mFilename != null) {
- tempFile = new File(mFilename + ".tmp");
+ String parent = originalFile.getParent();
+ String name = originalFile.getName();
+ String tempPrefix = UUID.randomUUID().toString() + "_";
+ tempFile = new File(parent, tempPrefix + name);
if (!originalFile.renameTo(tempFile)) {
throw new IOException("Couldn't rename to " + tempFile.getAbsolutePath());
}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 87c3bb9ffabe..5dc6f755d066 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -198,7 +198,10 @@ public class ImageReader implements AutoCloseable {
* {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
* </tr>
* </table>
- * Using other combinations may result in {@link IllegalArgumentException}.
+ * Using other combinations may result in {@link IllegalArgumentException}. Additionally,
+ * specifying {@link HardwareBuffer#USAGE_CPU_WRITE_RARELY} or
+ * {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN} and writing to the ImageReader's buffers
+ * might break assumptions made by some producers, and should be used with caution.
* </p>
* <p>
* If the {@link ImageReader} is used as an output target for a {@link
@@ -255,6 +258,7 @@ public class ImageReader implements AutoCloseable {
mWidth = width;
mHeight = height;
mFormat = format;
+ mUsage = usage;
mMaxImages = maxImages;
if (width < 1 || height < 1) {
@@ -768,6 +772,7 @@ public class ImageReader implements AutoCloseable {
private final int mWidth;
private final int mHeight;
private final int mFormat;
+ private final long mUsage;
private final int mMaxImages;
private final int mNumPlanes;
private final Surface mSurface;
@@ -909,7 +914,8 @@ public class ImageReader implements AutoCloseable {
throwISEIfImageIsInvalid();
if (mPlanes == null) {
- mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat);
+ mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat,
+ ImageReader.this.mUsage);
}
// Shallow copy is fine.
return mPlanes.clone();
@@ -1038,7 +1044,7 @@ public class ImageReader implements AutoCloseable {
private AtomicBoolean mIsDetached = new AtomicBoolean(false);
private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes,
- int readerFormat);
+ int readerFormat, long readerUsage);
private synchronized native int nativeGetWidth();
private synchronized native int nativeGetHeight();
private synchronized native int nativeGetFormat(int readerFormat);
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index d3e9c7e91056..8a17465c53b3 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -553,6 +553,12 @@ public class AudioPolicy {
}
}
+ /** @hide */
+ public void reset() {
+ setRegistration(null);
+ mConfig.reset();
+ }
+
public void setRegistration(String regId) {
synchronized (mLock) {
mRegistrationId = regId;
@@ -566,6 +572,11 @@ public class AudioPolicy {
sendMsg(MSG_POLICY_STATUS_CHANGE);
}
+ /**@hide*/
+ public String getRegistration() {
+ return mRegistrationId;
+ }
+
private boolean policyReadyToUse() {
synchronized (mLock) {
if (mStatus != POLICY_STATUS_REGISTERED) {
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index 91b9bb3f64c0..561a8847feed 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -162,7 +162,7 @@ public class AudioPolicyConfig implements Parcelable {
public String toLogFriendlyString () {
String textDump = new String("android.media.audiopolicy.AudioPolicyConfig:\n");
- textDump += mMixes.size() + " AudioMix: "+ mRegistrationId + "\n";
+ textDump += mMixes.size() + " AudioMix, reg:" + mRegistrationId + "\n";
for(AudioMix mix : mMixes) {
// write mix route flags
textDump += "* route flags=0x" + Integer.toHexString(mix.getRouteFlags()) + "\n";
@@ -220,6 +220,10 @@ public class AudioPolicyConfig implements Parcelable {
return textDump;
}
+ protected void reset() {
+ mMixCounter = 0;
+ }
+
protected void setRegistration(String regId) {
final boolean currentRegNull = (mRegistrationId == null) || mRegistrationId.isEmpty();
final boolean newRegNull = (regId == null) || regId.isEmpty();
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 0a02156ccf76..bd2a0eaa75c9 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -675,7 +675,8 @@ static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
return android_view_Surface_createFromIGraphicBufferProducer(env, gbp);
}
-static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) {
+static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image,
+ uint64_t ndkReaderUsage) {
ALOGV("%s", __FUNCTION__);
BufferItem* buffer = Image_getBufferItem(env, thiz);
if (buffer == NULL) {
@@ -684,8 +685,16 @@ static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image)
return;
}
- status_t res = lockImageFromBuffer(buffer,
- GRALLOC_USAGE_SW_READ_OFTEN, buffer->mFence->dup(), image);
+ uint32_t lockUsage;
+ if ((ndkReaderUsage & (AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY
+ | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN)) != 0) {
+ lockUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ } else {
+ lockUsage = GRALLOC_USAGE_SW_READ_OFTEN;
+ }
+
+ status_t res = lockImageFromBuffer(buffer, lockUsage, buffer->mFence->dup(), image);
+
if (res != OK) {
jniThrowExceptionFmt(env, "java/lang/RuntimeException",
"lock buffer failed for format 0x%x",
@@ -721,7 +730,7 @@ static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
}
static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
- int numPlanes, int readerFormat)
+ int numPlanes, int readerFormat, uint64_t ndkReaderUsage)
{
ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
int rowStride = 0;
@@ -754,7 +763,7 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
}
LockedImage lockedImg = LockedImage();
- Image_getLockedImage(env, thiz, &lockedImg);
+ Image_getLockedImage(env, thiz, &lockedImg, ndkReaderUsage);
if (env->ExceptionCheck()) {
return NULL;
}
@@ -839,7 +848,7 @@ static const JNINativeMethod gImageReaderMethods[] = {
};
static const JNINativeMethod gImageMethods[] = {
- {"nativeCreatePlanes", "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
+ {"nativeCreatePlanes", "(IIJ)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
(void*)Image_createSurfacePlanes },
{"nativeGetWidth", "()I", (void*)Image_getWidth },
{"nativeGetHeight", "()I", (void*)Image_getHeight },
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 033a32f550b7..55aac09b0f65 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -590,7 +590,7 @@ android_media_MediaPlayer_getSyncParams(JNIEnv *env, jobject thiz)
ALOGV("getSyncSettings: %d %d %f %f",
scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
- // sanity check params
+ // check params
if (scp.sync.mSource >= AVSYNC_SOURCE_MAX
|| scp.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
|| scp.sync.mTolerance < 0.f
diff --git a/media/jni/android_media_MediaSync.cpp b/media/jni/android_media_MediaSync.cpp
index f75200868a0d..d1ce30a3e827 100644
--- a/media/jni/android_media_MediaSync.cpp
+++ b/media/jni/android_media_MediaSync.cpp
@@ -451,7 +451,7 @@ static jobject android_media_MediaSync_getSyncParams(JNIEnv *env, jobject thiz)
ALOGV("getSyncParams: %d %d %f %f",
scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate);
- // sanity check params
+ // check params
if (scs.sync.mSource >= AVSYNC_SOURCE_MAX
|| scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
|| scs.sync.mTolerance < 0.f
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 3cd40818ae2a..5770c6797404 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -291,8 +291,9 @@ MQ& Dvr::getDvrMQ() {
C2DataIdInfo::C2DataIdInfo(uint32_t index, uint64_t value) : C2Param(kParamSize, index) {
CHECK(isGlobal());
CHECK_EQ(C2Param::INFO, kind());
- DummyInfo info{value};
- memcpy(this + 1, static_cast<C2Param *>(&info) + 1, kParamSize - sizeof(C2Param));
+ mInfo = StubInfo(value);
+ memcpy(static_cast<C2Param *>(this) + 1, static_cast<C2Param *>(&mInfo) + 1,
+ kParamSize - sizeof(C2Param));
}
/////////////// MediaEvent ///////////////////////
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 83e9db796363..fd2995917475 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -250,8 +250,9 @@ class C2DataIdInfo : public C2Param {
public:
C2DataIdInfo(uint32_t index, uint64_t value);
private:
- typedef C2GlobalParam<C2Info, C2Int64Value, 0> DummyInfo;
- static const size_t kParamSize = sizeof(DummyInfo);
+ typedef C2GlobalParam<C2Info, C2Int64Value, 0> StubInfo;
+ StubInfo mInfo;
+ static const size_t kParamSize = sizeof(StubInfo);
};
} // namespace android
diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp
index f4d65d0a397f..a74ae5307a36 100644
--- a/media/jni/audioeffect/Visualizer.cpp
+++ b/media/jni/audioeffect/Visualizer.cpp
@@ -34,21 +34,9 @@ namespace android {
// ---------------------------------------------------------------------------
-Visualizer::Visualizer (const String16& opPackageName,
- int32_t priority,
- effect_callback_t cbf,
- void* user,
- audio_session_t sessionId)
- : AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId),
- mCaptureRate(CAPTURE_RATE_DEF),
- mCaptureSize(CAPTURE_SIZE_DEF),
- mSampleRate(44100000),
- mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED),
- mMeasurementMode(MEASUREMENT_MODE_NONE),
- mCaptureCallBack(NULL),
- mCaptureCbkUser(NULL)
+Visualizer::Visualizer (const String16& opPackageName)
+ : AudioEffect(opPackageName)
{
- initCaptureSize();
}
Visualizer::~Visualizer()
@@ -58,6 +46,23 @@ Visualizer::~Visualizer()
setCaptureCallBack(NULL, NULL, 0, 0);
}
+status_t Visualizer::set(int32_t priority,
+ effect_callback_t cbf,
+ void* user,
+ audio_session_t sessionId,
+ audio_io_handle_t io,
+ const AudioDeviceTypeAddr& device,
+ bool probe)
+{
+ status_t status = AudioEffect::set(
+ SL_IID_VISUALIZATION, nullptr, priority, cbf, user, sessionId, io, device, probe);
+ if (status == NO_ERROR || status == ALREADY_EXISTS) {
+ initCaptureSize();
+ }
+ return status;
+}
+
+
void Visualizer::release()
{
ALOGV("Visualizer::release()");
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index d4672a95c6d8..8b6a62f25638 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -65,14 +65,22 @@ public:
/* Constructor.
* See AudioEffect constructor for details on parameters.
*/
- Visualizer(const String16& opPackageName,
- int32_t priority = 0,
- effect_callback_t cbf = NULL,
- void* user = NULL,
- audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ explicit Visualizer(const String16& opPackageName);
~Visualizer();
+ /**
+ * Initialize an uninitialized Visualizer.
+ * See AudioEffect 'set' function for details on parameters.
+ */
+ status_t set(int32_t priority = 0,
+ effect_callback_t cbf = NULL,
+ void* user = NULL,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
+ const AudioDeviceTypeAddr& device = {},
+ bool probe = false);
+
// Declared 'final' because we call this in ~Visualizer().
status_t setEnabled(bool enabled) final;
@@ -163,15 +171,15 @@ private:
uint32_t initCaptureSize();
Mutex mCaptureLock;
- uint32_t mCaptureRate;
- uint32_t mCaptureSize;
- uint32_t mSampleRate;
- uint32_t mScalingMode;
- uint32_t mMeasurementMode;
- capture_cbk_t mCaptureCallBack;
- void *mCaptureCbkUser;
+ uint32_t mCaptureRate = CAPTURE_RATE_DEF;
+ uint32_t mCaptureSize = CAPTURE_SIZE_DEF;
+ uint32_t mSampleRate = 44100000;
+ uint32_t mScalingMode = VISUALIZER_SCALING_MODE_NORMALIZED;
+ uint32_t mMeasurementMode = MEASUREMENT_MODE_NONE;
+ capture_cbk_t mCaptureCallBack = nullptr;
+ void *mCaptureCbkUser = nullptr;
sp<CaptureThread> mCaptureThread;
- uint32_t mCaptureFlags;
+ uint32_t mCaptureFlags = 0;
};
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index dbe7b4b619c9..96961ac21a2d 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -337,22 +337,21 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
}
// create the native AudioEffect object
- lpAudioEffect = new AudioEffect(typeStr,
- String16(opPackageNameStr.c_str()),
- uuidStr,
- priority,
- effectCallback,
- &lpJniStorage->mCallbackData,
- (audio_session_t) sessionId,
- AUDIO_IO_HANDLE_NONE,
- device,
- probe);
+ lpAudioEffect = new AudioEffect(String16(opPackageNameStr.c_str()));
if (lpAudioEffect == 0) {
ALOGE("Error creating AudioEffect");
goto setup_failure;
}
-
+ lpAudioEffect->set(typeStr,
+ uuidStr,
+ priority,
+ effectCallback,
+ &lpJniStorage->mCallbackData,
+ (audio_session_t) sessionId,
+ AUDIO_IO_HANDLE_NONE,
+ device,
+ probe);
lStatus = AudioEffectJni::translateNativeErrorToJava(lpAudioEffect->initCheck());
if (lStatus != AUDIOEFFECT_SUCCESS && lStatus != AUDIOEFFECT_ERROR_ALREADY_EXISTS) {
ALOGE("AudioEffect initCheck failed %d", lStatus);
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index f9a77f474c50..4c5970a30a05 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -382,15 +382,15 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
}
// create the native Visualizer object
- lpVisualizer = new Visualizer(String16(opPackageNameStr.c_str()),
- 0,
- android_media_visualizer_effect_callback,
- lpJniStorage,
- (audio_session_t) sessionId);
+ lpVisualizer = new Visualizer(String16(opPackageNameStr.c_str()));
if (lpVisualizer == 0) {
ALOGE("Error creating Visualizer");
goto setup_failure;
}
+ lpVisualizer->set(0,
+ android_media_visualizer_effect_callback,
+ lpJniStorage,
+ (audio_session_t) sessionId);
lStatus = translateError(lpVisualizer->initCheck());
if (lStatus != VISUALIZER_SUCCESS && lStatus != VISUALIZER_ERROR_ALREADY_EXISTS) {
diff --git a/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java b/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java
index ce81a18eeaa8..ab9ae8ab2ac8 100644
--- a/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java
+++ b/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java
@@ -43,7 +43,7 @@ public class FilterFunction {
public Frame execute(KeyValueMap inputMap) {
int filterOutCount = mFilter.getNumberOfOutputs();
- // Sanity checks
+ // Validation checks
if (filterOutCount > 1) {
throw new RuntimeException("Calling execute on filter " + mFilter + " with multiple "
+ "outputs! Use executeMulti() instead!");
diff --git a/media/mca/filterfw/jni/jni_native_program.cpp b/media/mca/filterfw/jni/jni_native_program.cpp
index 14246078225e..cd4f7187c250 100644
--- a/media/mca/filterfw/jni/jni_native_program.cpp
+++ b/media/mca/filterfw/jni/jni_native_program.cpp
@@ -134,7 +134,7 @@ jboolean Java_android_filterfw_core_NativeProgram_callNativeProcess(JNIEnv* env,
jobject output) {
NativeProgram* program = ConvertFromJava<NativeProgram>(env, thiz);
- // Sanity checks
+ // Validation checks
if (!program || !inputs) {
return JNI_FALSE;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
index 0ae640dd7910..e74bda8a6b35 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
@@ -16,16 +16,6 @@
package com.android.mediaframeworktest.helpers;
-import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
-
-import junit.framework.Assert;
-
-import org.mockito.Mockito;
-
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
@@ -64,6 +54,16 @@ import android.view.WindowManager;
import androidx.test.InstrumentationRegistry;
+import com.android.ex.camera2.blocking.BlockingCameraManager;
+import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
+
+import junit.framework.Assert;
+
+import org.mockito.Mockito;
+
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
@@ -77,8 +77,8 @@ import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@@ -225,7 +225,7 @@ public class CameraTestUtils extends Assert {
}
/**
- * Dummy listener that release the image immediately once it is available.
+ * Mock listener that release the image immediately once it is available.
*
* <p>
* It can be used for the case where we don't care the image data at all.
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/Preconditions.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/Preconditions.java
index 96b0424595e3..a77b2898c5e0 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/Preconditions.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/Preconditions.java
@@ -22,7 +22,7 @@ import java.util.Objects;
/**
* Helper set of methods to perform precondition checks before starting method execution.
*
- * <p>Typically used to sanity check arguments or the current object state.</p>
+ * <p>Typically used to check arguments or the current object state.</p>
*/
/**
* (non-Javadoc)
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
index b3f443b30a70..9a64b58a080d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
@@ -16,7 +16,7 @@
package com.android.mediaframeworktest.helpers;
-import junit.framework.Assert;
+import static com.android.mediaframeworktest.helpers.AssertHelpers.assertArrayContainsAnyOf;
import android.graphics.ImageFormat;
import android.graphics.Rect;
@@ -31,6 +31,8 @@ import android.util.Range;
import android.util.Rational;
import android.util.Size;
+import junit.framework.Assert;
+
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
@@ -40,8 +42,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import static com.android.mediaframeworktest.helpers.AssertHelpers.assertArrayContainsAnyOf;
-
/**
* Helpers to get common static info out of the camera.
*
@@ -435,7 +435,7 @@ public class StaticMetadata {
}
/**
- * Get max AE regions and do sanity check.
+ * Get max AE regions and do validation check.
*
* @return AE max regions supported by the camera device
*/
@@ -448,7 +448,7 @@ public class StaticMetadata {
}
/**
- * Get max AWB regions and do sanity check.
+ * Get max AWB regions and do validation check.
*
* @return AWB max regions supported by the camera device
*/
@@ -461,7 +461,7 @@ public class StaticMetadata {
}
/**
- * Get max AF regions and do sanity check.
+ * Get max AF regions and do validation check.
*
* @return AF max regions supported by the camera device
*/
@@ -545,7 +545,7 @@ public class StaticMetadata {
}
/**
- * Get available thumbnail sizes and do the sanity check.
+ * Get available thumbnail sizes and do the validation check.
*
* @return The array of available thumbnail sizes
*/
@@ -573,7 +573,7 @@ public class StaticMetadata {
}
/**
- * Get available focal lengths and do the sanity check.
+ * Get available focal lengths and do the validation check.
*
* @return The array of available focal lengths
*/
@@ -594,7 +594,7 @@ public class StaticMetadata {
}
/**
- * Get available apertures and do the sanity check.
+ * Get available apertures and do the validation check.
*
* @return The non-null array of available apertures
*/
@@ -909,7 +909,7 @@ public class StaticMetadata {
}
/**
- * Get hyperfocalDistance and do the sanity check.
+ * Get hyperfocalDistance and do the validation check.
* <p>
* Note that, this tag is optional, will return -1 if this tag is not
* available.
@@ -1068,7 +1068,7 @@ public class StaticMetadata {
}
/**
- * get android.control.availableModes and do the sanity check.
+ * get android.control.availableModes and do the validation check.
*
* @return available control modes.
*/
@@ -1124,7 +1124,7 @@ public class StaticMetadata {
}
/**
- * Get aeAvailableModes and do the sanity check.
+ * Get aeAvailableModes and do the validation check.
*
* <p>Depending on the check level this class has, for WAR or COLLECT levels,
* If the aeMode list is invalid, return an empty mode array. The the caller doesn't
@@ -1196,7 +1196,7 @@ public class StaticMetadata {
}
/**
- * Get available AWB modes and do the sanity check.
+ * Get available AWB modes and do the validation check.
*
* @return array that contains available AWB modes, empty array if awbAvailableModes is
* unavailable.
@@ -1222,7 +1222,7 @@ public class StaticMetadata {
}
/**
- * Get available AF modes and do the sanity check.
+ * Get available AF modes and do the validation check.
*
* @return array that contains available AF modes, empty array if afAvailableModes is
* unavailable.
@@ -1580,7 +1580,7 @@ public class StaticMetadata {
}
/**
- * Get value of key android.control.aeCompensationStep and do the sanity check.
+ * Get value of key android.control.aeCompensationStep and do the validation check.
*
* @return default value if the value is null.
*/
@@ -1605,7 +1605,7 @@ public class StaticMetadata {
}
/**
- * Get value of key android.control.aeCompensationRange and do the sanity check.
+ * Get value of key android.control.aeCompensationRange and do the validation check.
*
* @return default value if the value is null or malformed.
*/
@@ -1635,7 +1635,7 @@ public class StaticMetadata {
}
/**
- * Get availableVideoStabilizationModes and do the sanity check.
+ * Get availableVideoStabilizationModes and do the validation check.
*
* @return available video stabilization modes, empty array if it is unavailable.
*/
@@ -1666,7 +1666,7 @@ public class StaticMetadata {
}
/**
- * Get availableOpticalStabilization and do the sanity check.
+ * Get availableOpticalStabilization and do the validation check.
*
* @return available optical stabilization modes, empty array if it is unavailable.
*/
@@ -1780,7 +1780,7 @@ public class StaticMetadata {
}
/**
- * Get max pipeline depth and do the sanity check.
+ * Get max pipeline depth and do the validation check.
*
* @return max pipeline depth, default value if it is not available.
*/
@@ -1846,7 +1846,7 @@ public class StaticMetadata {
/**
- * Get available capabilities and do the sanity check.
+ * Get available capabilities and do the validation check.
*
* @return reported available capabilities list, empty list if the value is unavailable.
*/
@@ -2070,7 +2070,7 @@ public class StaticMetadata {
}
/**
- * Get max number of output raw streams and do the basic sanity check.
+ * Get max number of output raw streams and do the basic validation check.
*
* @return reported max number of raw output stream
*/
@@ -2083,7 +2083,7 @@ public class StaticMetadata {
}
/**
- * Get max number of output processed streams and do the basic sanity check.
+ * Get max number of output processed streams and do the basic validation check.
*
* @return reported max number of processed output stream
*/
@@ -2096,7 +2096,7 @@ public class StaticMetadata {
}
/**
- * Get max number of output stalling processed streams and do the basic sanity check.
+ * Get max number of output stalling processed streams and do the basic validation check.
*
* @return reported max number of stalling processed output stream
*/
@@ -2109,7 +2109,7 @@ public class StaticMetadata {
}
/**
- * Get lens facing and do the sanity check
+ * Get lens facing and do the validation check
* @return lens facing, return default value (BACK) if value is unavailable.
*/
public int getLensFacingChecked() {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2CaptureRequestTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2CaptureRequestTest.java
index 31b79677f9ff..47caf0a0bc9b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2CaptureRequestTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2CaptureRequestTest.java
@@ -309,7 +309,7 @@ public class Camera2CaptureRequestTest extends Camera2SurfaceViewTestCase {
private void changeExposure(CaptureRequest.Builder requestBuilder,
long expTime, int sensitivity) {
// Check if the max analog sensitivity is available and no larger than max sensitivity.
- // The max analog sensitivity is not actually used here. This is only an extra sanity check.
+ // The max analog sensitivity is not actually used here. This is only an extra check.
mStaticInfo.getMaxAnalogSensitivityChecked();
expTime = mStaticInfo.getExposureClampToRange(expTime);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java
index 6a4db5791d5c..dc8da4868df3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java
@@ -985,7 +985,7 @@ public class Camera2RecordingTest extends Camera2SurfaceViewTestCase {
}
/**
- * Validate video snapshot capture image object sanity and test.
+ * Validate video snapshot capture image object soundness and test.
*
* <p> Check for size, format and jpeg decoding</p>
*
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2StillCaptureTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2StillCaptureTest.java
index f7373f7b68db..cbdcc36eea3a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2StillCaptureTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2StillCaptureTest.java
@@ -570,7 +570,7 @@ public class Camera2StillCaptureTest extends Camera2SurfaceViewTestCase {
}
/**
- * Validate JPEG capture image object sanity and test.
+ * Validate JPEG capture image object soundness and test.
* <p>
* In addition to image object sanity, this function also does the decoding
* test, which is slower.
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 5aaca435e71e..54618a5da3a3 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -24189,6 +24189,7 @@ package android.media {
method @NonNull public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations();
method @NonNull public java.util.List<android.media.AudioRecordingConfiguration> getActiveRecordingConfigurations();
method public int getAllowedCapturePolicy();
+ method public int getAudioHwSyncForSession(int);
method public android.media.AudioDeviceInfo[] getDevices(int);
method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
method public int getMode();
@@ -46014,6 +46015,7 @@ package android.telephony {
method @Nullable public android.net.LinkProperties getLinkProperties();
method public int getNetworkType();
method public int getState();
+ method public int getTransportType();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
}
diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt
index 45ff6d3893e3..3c0b955119a6 100644
--- a/non-updatable-api/module-lib-current.txt
+++ b/non-updatable-api/module-lib-current.txt
@@ -31,6 +31,14 @@ package android.graphics {
}
+package android.media {
+
+ public class AudioManager {
+ field public static final int FLAG_FROM_KEY = 4096; // 0x1000
+ }
+
+}
+
package android.os {
public class Binder implements android.os.IBinder {
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index 222e563d4f96..844e929774a1 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -4141,6 +4141,7 @@ package android.media {
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) public long getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -4159,6 +4160,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
@@ -4169,6 +4171,11 @@ package android.media {
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
+ field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+ field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
+ field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
+ field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
+ field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
field public static final int SUCCESS = 0; // 0x0
}
@@ -9706,6 +9713,7 @@ package android.telephony {
method @Deprecated public int getDataConnectionApnTypeBitMask();
method @Deprecated public int getDataConnectionFailCause();
method @Deprecated public int getDataConnectionState();
+ method public int getId();
}
public final class PreciseDisconnectCause {
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
index c7af8c8778ce..d0776aef78b6 100644
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
@@ -40,18 +40,18 @@ public final class Hkdf {
*
* <p>IMPORTANT: The use or edit of this method requires a security review.
*
- * @param masterKey Master key from which to derive sub-keys.
+ * @param mainKey Main key from which to derive sub-keys.
* @param salt A randomly generated 256-bit byte string.
* @param data Arbitrary information that is bound to the derived key (i.e., used in its
* creation).
- * @return Raw derived key bytes = HKDF-SHA256(masterKey, salt, data).
+ * @return Raw derived key bytes = HKDF-SHA256(mainKey, salt, data).
* @throws InvalidKeyException If the salt can not be used as a valid key.
*/
- static byte[] hkdf(byte[] masterKey, byte[] salt, byte[] data) throws InvalidKeyException {
- Objects.requireNonNull(masterKey, "HKDF requires master key to be set.");
+ static byte[] hkdf(byte[] mainKey, byte[] salt, byte[] data) throws InvalidKeyException {
+ Objects.requireNonNull(mainKey, "HKDF requires main key to be set.");
Objects.requireNonNull(salt, "HKDF requires a salt.");
Objects.requireNonNull(data, "No data provided to HKDF.");
- return hkdfSha256Expand(hkdfSha256Extract(masterKey, salt), data);
+ return hkdfSha256Expand(hkdfSha256Extract(mainKey, salt), data);
}
private Hkdf() {}
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index cf967c02bec5..039f2c039ded 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -24,12 +24,35 @@
<bool name="config_enableFullscreenUserSwitcher">true</bool>
- <!-- configure which system ui bars should be displayed -->
+ <!-- Configure which system bars should be displayed. -->
<bool name="config_enableTopNavigationBar">true</bool>
<bool name="config_enableLeftNavigationBar">false</bool>
<bool name="config_enableRightNavigationBar">false</bool>
<bool name="config_enableBottomNavigationBar">true</bool>
+ <!-- Configure the type of each system bar. Each system bar must have a unique type. -->
+ <!-- STATUS_BAR = 0-->
+ <!-- NAVIGATION_BAR = 1-->
+ <!-- STATUS_BAR_EXTRA = 2-->
+ <!-- NAVIGATION_BAR_EXTRA = 3-->
+ <integer name="config_topSystemBarType">0</integer>
+ <integer name="config_leftSystemBarType">2</integer>
+ <integer name="config_rightSystemBarType">3</integer>
+ <integer name="config_bottomSystemBarType">1</integer>
+
+ <!-- Configure the relative z-order among the system bars. When two system bars overlap (e.g.
+ if both top bar and left bar are enabled, it creates an overlapping space in the upper left
+ corner), the system bar with the higher z-order takes the overlapping space and padding is
+ applied to the other bar.-->
+ <!-- NOTE: If two overlapping system bars have the same z-order, SystemBarConfigs will throw a
+ RuntimeException, since their placing order cannot be determined. Bars that do not overlap
+ are allowed to have the same z-order. -->
+ <!-- NOTE: If the z-order of a bar is 10 or above, it will also appear on top of HUN's. -->
+ <integer name="config_topSystemBarZOrder">1</integer>
+ <integer name="config_leftSystemBarZOrder">0</integer>
+ <integer name="config_rightSystemBarZOrder">0</integer>
+ <integer name="config_bottomSystemBarZOrder">10</integer>
+
<!-- Disable normal notification rendering; we handle that ourselves -->
<bool name="config_renderNotifications">false</bool>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 7b6dceb5fcd7..f4e704ea373e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -38,6 +38,8 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.doze.DozeHost;
+import com.android.systemui.pip.phone.PipMenuActivity;
+import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
@@ -134,9 +136,20 @@ public abstract class CarSystemUIModule {
}
@Singleton
- @Binds
- abstract DisplayImeController bindDisplayImeController(
- DisplaySystemBarsController displaySystemBarsController);
+ @Provides
+ static DisplayImeController provideDisplayImeController(Context context,
+ IWindowManager wmService, DisplayController displayController,
+ @Main Handler mainHandler, TransactionPool transactionPool) {
+ return new DisplaySystemBarsController.Builder(context, wmService, displayController,
+ mainHandler, transactionPool).build();
+ }
+
+ @Singleton
+ @PipMenuActivityClass
+ @Provides
+ static Class<?> providePipMenuActivityClass() {
+ return PipMenuActivity.class;
+ }
@Binds
abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index 35b2080dddf9..9584850fde7c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
@@ -16,12 +16,8 @@
package com.android.systemui.car.navigationbar;
-import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
-import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.ITYPE_TOP_GESTURES;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
@@ -30,13 +26,11 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.PixelFormat;
import android.inputmethodservice.InputMethodService;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.Display;
-import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsetsController;
@@ -47,7 +41,6 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.internal.view.AppearanceRegion;
-import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarDeviceProvisionedListener;
@@ -76,7 +69,6 @@ import dagger.Lazy;
/** Navigation bars customized for the automotive use case. */
public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks {
-
private final Resources mResources;
private final CarNavigationBarController mCarNavigationBarController;
private final SysuiDarkIconDispatcher mStatusBarIconController;
@@ -93,6 +85,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
private final Lazy<StatusBarIconController> mIconControllerLazy;
private final int mDisplayId;
+ private final SystemBarConfigs mSystemBarConfigs;
private StatusBarSignalPolicy mSignalPolicy;
private ActivityManagerWrapper mActivityManagerWrapper;
@@ -141,7 +134,8 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
IStatusBarService barService,
Lazy<KeyguardStateController> keyguardStateControllerLazy,
Lazy<PhoneStatusBarPolicy> iconPolicyLazy,
- Lazy<StatusBarIconController> iconControllerLazy
+ Lazy<StatusBarIconController> iconControllerLazy,
+ SystemBarConfigs systemBarConfigs
) {
super(context);
mResources = resources;
@@ -158,6 +152,7 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
mKeyguardStateControllerLazy = keyguardStateControllerLazy;
mIconPolicyLazy = iconPolicyLazy;
mIconControllerLazy = iconControllerLazy;
+ mSystemBarConfigs = systemBarConfigs;
mDisplayId = context.getDisplayId();
}
@@ -344,103 +339,63 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
private void buildNavBarContent() {
mTopNavigationBarView = mCarNavigationBarController.getTopBar(isDeviceSetupForUser());
if (mTopNavigationBarView != null) {
+ mSystemBarConfigs.insetSystemBar(SystemBarConfigs.TOP, mTopNavigationBarView);
mTopNavigationBarWindow.addView(mTopNavigationBarView);
}
mBottomNavigationBarView = mCarNavigationBarController.getBottomBar(isDeviceSetupForUser());
if (mBottomNavigationBarView != null) {
+ mSystemBarConfigs.insetSystemBar(SystemBarConfigs.BOTTOM, mBottomNavigationBarView);
mBottomNavigationBarWindow.addView(mBottomNavigationBarView);
}
mLeftNavigationBarView = mCarNavigationBarController.getLeftBar(isDeviceSetupForUser());
if (mLeftNavigationBarView != null) {
+ mSystemBarConfigs.insetSystemBar(SystemBarConfigs.LEFT, mLeftNavigationBarView);
mLeftNavigationBarWindow.addView(mLeftNavigationBarView);
}
mRightNavigationBarView = mCarNavigationBarController.getRightBar(isDeviceSetupForUser());
if (mRightNavigationBarView != null) {
+ mSystemBarConfigs.insetSystemBar(SystemBarConfigs.RIGHT, mRightNavigationBarView);
mRightNavigationBarWindow.addView(mRightNavigationBarView);
}
}
private void attachNavBarWindows() {
- if (mTopNavigationBarWindow != null) {
- int height = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height);
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- height,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- lp.setTitle("TopCarNavigationBar");
- lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
- lp.setFitInsetsTypes(0);
- lp.windowAnimations = 0;
- lp.gravity = Gravity.TOP;
- mWindowManager.addView(mTopNavigationBarWindow, lp);
- }
-
- if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) {
- mBottomNavBarVisible = true;
- int height = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height);
-
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- height,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- lp.setTitle("BottomCarNavigationBar");
- lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR, ITYPE_BOTTOM_GESTURES};
- lp.windowAnimations = 0;
- lp.gravity = Gravity.BOTTOM;
- mWindowManager.addView(mBottomNavigationBarWindow, lp);
- }
-
- if (mLeftNavigationBarWindow != null) {
- int width = mResources.getDimensionPixelSize(
- R.dimen.car_left_navigation_bar_width);
- WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
- width, ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- leftlp.setTitle("LeftCarNavigationBar");
- leftlp.providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR};
- leftlp.setFitInsetsTypes(0);
- leftlp.windowAnimations = 0;
- leftlp.gravity = Gravity.LEFT;
- mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
- }
+ mSystemBarConfigs.getSystemBarSidesByZOrder().forEach(this::attachNavBarBySide);
+ }
- if (mRightNavigationBarWindow != null) {
- int width = mResources.getDimensionPixelSize(
- R.dimen.car_right_navigation_bar_width);
- WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
- width, ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- rightlp.setTitle("RightCarNavigationBar");
- rightlp.providesInsetsTypes = new int[]{ITYPE_EXTRA_NAVIGATION_BAR};
- rightlp.setFitInsetsTypes(0);
- rightlp.windowAnimations = 0;
- rightlp.gravity = Gravity.RIGHT;
- mWindowManager.addView(mRightNavigationBarWindow, rightlp);
+ private void attachNavBarBySide(int side) {
+ switch(side) {
+ case SystemBarConfigs.TOP:
+ if (mTopNavigationBarWindow != null) {
+ mWindowManager.addView(mTopNavigationBarWindow,
+ mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.TOP));
+ }
+ break;
+ case SystemBarConfigs.BOTTOM:
+ if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) {
+ mBottomNavBarVisible = true;
+
+ mWindowManager.addView(mBottomNavigationBarWindow,
+ mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.BOTTOM));
+ }
+ break;
+ case SystemBarConfigs.LEFT:
+ if (mLeftNavigationBarWindow != null) {
+ mWindowManager.addView(mLeftNavigationBarWindow,
+ mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.LEFT));
+ }
+ break;
+ case SystemBarConfigs.RIGHT:
+ if (mRightNavigationBarWindow != null) {
+ mWindowManager.addView(mRightNavigationBarWindow,
+ mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.RIGHT));
+ }
+ break;
+ default:
+ return;
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
index ca780ae645c9..fe26040c5eae 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
@@ -22,7 +22,6 @@ import android.view.ViewGroup;
import androidx.annotation.Nullable;
-import com.android.systemui.R;
import com.android.systemui.car.hvac.HvacController;
import javax.inject.Inject;
@@ -61,7 +60,8 @@ public class CarNavigationBarController {
NavigationBarViewFactory navigationBarViewFactory,
ButtonSelectionStateController buttonSelectionStateController,
Lazy<HvacController> hvacControllerLazy,
- ButtonRoleHolderController buttonRoleHolderController) {
+ ButtonRoleHolderController buttonRoleHolderController,
+ SystemBarConfigs systemBarConfigs) {
mContext = context;
mNavigationBarViewFactory = navigationBarViewFactory;
mButtonSelectionStateController = buttonSelectionStateController;
@@ -69,10 +69,10 @@ public class CarNavigationBarController {
mButtonRoleHolderController = buttonRoleHolderController;
// Read configuration.
- mShowTop = mContext.getResources().getBoolean(R.bool.config_enableTopNavigationBar);
- mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
- mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
- mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
+ mShowTop = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.TOP);
+ mShowBottom = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.BOTTOM);
+ mShowLeft = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.LEFT);
+ mShowRight = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.RIGHT);
}
/**
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
index 0ced4021ce38..ab401bbf06bb 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
@@ -16,14 +16,10 @@
package com.android.systemui.car.navigationbar;
-import static android.view.WindowInsets.Type.systemBars;
-
import android.content.Context;
-import android.graphics.Insets;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import android.view.WindowInsets;
import android.widget.LinearLayout;
import com.android.systemui.Dependency;
@@ -80,30 +76,6 @@ public class CarNavigationBarView extends LinearLayout {
setFocusable(false);
}
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
- applyMargins(windowInsets.getInsets(systemBars()));
- return windowInsets;
- }
-
- private void applyMargins(Insets insets) {
- final int count = getChildCount();
- for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
- if (child.getLayoutParams() instanceof LayoutParams) {
- LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.rightMargin != insets.right || lp.leftMargin != insets.left
- || lp.topMargin != insets.top || lp.bottomMargin != insets.bottom) {
- lp.rightMargin = insets.right;
- lp.leftMargin = insets.left;
- lp.topMargin = insets.top;
- lp.bottomMargin = insets.bottom;
- child.requestLayout();
- }
- }
- }
- }
-
// Used to forward touch events even if the touch was initiated from a child component
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
new file mode 100644
index 000000000000..3527bf93682f
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
@@ -0,0 +1,380 @@
+/*
+ * 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.systemui.car.navigationbar;
+
+import android.annotation.IntDef;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.InsetsState;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Reads configs for system bars for each side (TOP, BOTTOM, LEFT, and RIGHT) and returns the
+ * corresponding {@link android.view.WindowManager.LayoutParams} per the configuration.
+ */
+@Singleton
+public class SystemBarConfigs {
+
+ private static final String TAG = SystemBarConfigs.class.getSimpleName();
+ // The z-order from which system bars will start to appear on top of HUN's.
+ private static final int HUN_ZORDER = 10;
+
+ @IntDef(value = {TOP, BOTTOM, LEFT, RIGHT})
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+ private @interface SystemBarSide {
+ }
+
+ public static final int TOP = 0;
+ public static final int BOTTOM = 1;
+ public static final int LEFT = 2;
+ public static final int RIGHT = 3;
+
+ /*
+ NOTE: The elements' order in the map below must be preserved as-is since the correct
+ corresponding values are obtained by the index.
+ */
+ private static final int[] BAR_TYPE_MAP = {
+ InsetsState.ITYPE_STATUS_BAR,
+ InsetsState.ITYPE_NAVIGATION_BAR,
+ InsetsState.ITYPE_CLIMATE_BAR,
+ InsetsState.ITYPE_EXTRA_NAVIGATION_BAR
+ };
+
+ private static final Map<@SystemBarSide Integer, Integer> BAR_GRAVITY_MAP = new ArrayMap<>();
+ private static final Map<@SystemBarSide Integer, String> BAR_TITLE_MAP = new ArrayMap<>();
+ private static final Map<@SystemBarSide Integer, Integer> BAR_GESTURE_MAP = new ArrayMap<>();
+
+ private final Resources mResources;
+ private final Map<@SystemBarSide Integer, SystemBarConfig> mSystemBarConfigMap =
+ new ArrayMap<>();
+ private final List<@SystemBarSide Integer> mSystemBarSidesByZOrder = new ArrayList<>();
+
+ private boolean mTopNavBarEnabled;
+ private boolean mBottomNavBarEnabled;
+ private boolean mLeftNavBarEnabled;
+ private boolean mRightNavBarEnabled;
+
+ @Inject
+ public SystemBarConfigs(@Main Resources resources) {
+ mResources = resources;
+
+ populateMaps();
+ readConfigs();
+ checkEnabledBarsHaveUniqueBarTypes();
+ setInsetPaddingsForOverlappingCorners();
+ sortSystemBarSidesByZOrder();
+ }
+
+ protected WindowManager.LayoutParams getLayoutParamsBySide(@SystemBarSide int side) {
+ return mSystemBarConfigMap.get(side) != null
+ ? mSystemBarConfigMap.get(side).getLayoutParams() : null;
+ }
+
+ protected boolean getEnabledStatusBySide(@SystemBarSide int side) {
+ switch (side) {
+ case TOP:
+ return mTopNavBarEnabled;
+ case BOTTOM:
+ return mBottomNavBarEnabled;
+ case LEFT:
+ return mLeftNavBarEnabled;
+ case RIGHT:
+ return mRightNavBarEnabled;
+ default:
+ return false;
+ }
+ }
+
+ protected void insetSystemBar(@SystemBarSide int side, CarNavigationBarView view) {
+ int[] paddings = mSystemBarConfigMap.get(side).getPaddings();
+ view.setPadding(paddings[2], paddings[0], paddings[3], paddings[1]);
+ }
+
+ protected List<Integer> getSystemBarSidesByZOrder() {
+ return mSystemBarSidesByZOrder;
+ }
+
+ @VisibleForTesting
+ protected static int getHunZOrder() {
+ return HUN_ZORDER;
+ }
+
+ private static void populateMaps() {
+ BAR_GRAVITY_MAP.put(TOP, Gravity.TOP);
+ BAR_GRAVITY_MAP.put(BOTTOM, Gravity.BOTTOM);
+ BAR_GRAVITY_MAP.put(LEFT, Gravity.LEFT);
+ BAR_GRAVITY_MAP.put(RIGHT, Gravity.RIGHT);
+
+ BAR_TITLE_MAP.put(TOP, "TopCarSystemBar");
+ BAR_TITLE_MAP.put(BOTTOM, "BottomCarSystemBar");
+ BAR_TITLE_MAP.put(LEFT, "LeftCarSystemBar");
+ BAR_TITLE_MAP.put(RIGHT, "RightCarSystemBar");
+
+ BAR_GESTURE_MAP.put(TOP, InsetsState.ITYPE_TOP_GESTURES);
+ BAR_GESTURE_MAP.put(BOTTOM, InsetsState.ITYPE_BOTTOM_GESTURES);
+ BAR_GESTURE_MAP.put(LEFT, InsetsState.ITYPE_LEFT_GESTURES);
+ BAR_GESTURE_MAP.put(RIGHT, InsetsState.ITYPE_RIGHT_GESTURES);
+ }
+
+ private void readConfigs() {
+ mTopNavBarEnabled = mResources.getBoolean(R.bool.config_enableTopNavigationBar);
+ mBottomNavBarEnabled = mResources.getBoolean(R.bool.config_enableBottomNavigationBar);
+ mLeftNavBarEnabled = mResources.getBoolean(R.bool.config_enableLeftNavigationBar);
+ mRightNavBarEnabled = mResources.getBoolean(R.bool.config_enableRightNavigationBar);
+
+ if (mTopNavBarEnabled) {
+ SystemBarConfig topBarConfig =
+ new SystemBarConfigBuilder()
+ .setSide(TOP)
+ .setGirth(mResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height))
+ .setBarType(mResources.getInteger(R.integer.config_topSystemBarType))
+ .setZOrder(mResources.getInteger(R.integer.config_topSystemBarZOrder))
+ .build();
+ mSystemBarConfigMap.put(TOP, topBarConfig);
+ }
+
+ if (mBottomNavBarEnabled) {
+ SystemBarConfig bottomBarConfig =
+ new SystemBarConfigBuilder()
+ .setSide(BOTTOM)
+ .setGirth(mResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height))
+ .setBarType(mResources.getInteger(R.integer.config_bottomSystemBarType))
+ .setZOrder(
+ mResources.getInteger(R.integer.config_bottomSystemBarZOrder))
+ .build();
+ mSystemBarConfigMap.put(BOTTOM, bottomBarConfig);
+ }
+
+ if (mLeftNavBarEnabled) {
+ SystemBarConfig leftBarConfig =
+ new SystemBarConfigBuilder()
+ .setSide(LEFT)
+ .setGirth(mResources.getDimensionPixelSize(
+ R.dimen.car_left_navigation_bar_width))
+ .setBarType(mResources.getInteger(R.integer.config_leftSystemBarType))
+ .setZOrder(mResources.getInteger(R.integer.config_leftSystemBarZOrder))
+ .build();
+ mSystemBarConfigMap.put(LEFT, leftBarConfig);
+ }
+
+ if (mRightNavBarEnabled) {
+ SystemBarConfig rightBarConfig =
+ new SystemBarConfigBuilder()
+ .setSide(RIGHT)
+ .setGirth(mResources.getDimensionPixelSize(
+ R.dimen.car_right_navigation_bar_width))
+ .setBarType(mResources.getInteger(R.integer.config_rightSystemBarType))
+ .setZOrder(mResources.getInteger(R.integer.config_rightSystemBarZOrder))
+ .build();
+ mSystemBarConfigMap.put(RIGHT, rightBarConfig);
+ }
+ }
+
+ private void checkEnabledBarsHaveUniqueBarTypes() throws RuntimeException {
+ Set<Integer> barTypesUsed = new ArraySet<>();
+ int enabledNavBarCount = mSystemBarConfigMap.size();
+
+ for (SystemBarConfig systemBarConfig : mSystemBarConfigMap.values()) {
+ barTypesUsed.add(systemBarConfig.getBarType());
+ }
+
+ // The number of bar types used cannot be fewer than that of enabled system bars.
+ if (barTypesUsed.size() < enabledNavBarCount) {
+ throw new RuntimeException("Each enabled system bar must have a unique bar type. Check "
+ + "the configuration in config.xml");
+ }
+ }
+
+ private void setInsetPaddingsForOverlappingCorners() {
+ setInsetPaddingForOverlappingCorner(TOP, LEFT);
+ setInsetPaddingForOverlappingCorner(TOP, RIGHT);
+ setInsetPaddingForOverlappingCorner(BOTTOM, LEFT);
+ setInsetPaddingForOverlappingCorner(BOTTOM, RIGHT);
+ }
+
+ private void setInsetPaddingForOverlappingCorner(@SystemBarSide int horizontalSide,
+ @SystemBarSide int verticalSide) {
+
+ if (isVerticalBar(horizontalSide) || isHorizontalBar(verticalSide)) {
+ Log.w(TAG, "configureBarPaddings: Returning immediately since the horizontal and "
+ + "vertical sides were not provided correctly.");
+ return;
+ }
+
+ SystemBarConfig horizontalBarConfig = mSystemBarConfigMap.get(horizontalSide);
+ SystemBarConfig verticalBarConfig = mSystemBarConfigMap.get(verticalSide);
+
+ if (verticalBarConfig != null && horizontalBarConfig != null) {
+ int horizontalBarZOrder = horizontalBarConfig.getZOrder();
+ int horizontalBarGirth = horizontalBarConfig.getGirth();
+ int verticalBarZOrder = verticalBarConfig.getZOrder();
+ int verticalBarGirth = verticalBarConfig.getGirth();
+
+ if (horizontalBarZOrder > verticalBarZOrder) {
+ verticalBarConfig.setPaddingBySide(horizontalSide, horizontalBarGirth);
+ } else if (horizontalBarZOrder < verticalBarZOrder) {
+ horizontalBarConfig.setPaddingBySide(verticalSide, verticalBarGirth);
+ } else {
+ throw new RuntimeException(
+ BAR_TITLE_MAP.get(horizontalSide) + " " + BAR_TITLE_MAP.get(verticalSide)
+ + " have the same Z-Order, and so their placing order cannot be "
+ + "determined. Determine which bar should be placed on top of the "
+ + "other bar and change the Z-order in config.xml accordingly."
+ );
+ }
+ }
+ }
+
+ private void sortSystemBarSidesByZOrder() {
+ List<SystemBarConfig> systemBarsByZOrder = new ArrayList<>(mSystemBarConfigMap.values());
+
+ systemBarsByZOrder.sort(new Comparator<SystemBarConfig>() {
+ @Override
+ public int compare(SystemBarConfig o1, SystemBarConfig o2) {
+ return o1.getZOrder() - o2.getZOrder();
+ }
+ });
+
+ systemBarsByZOrder.forEach(systemBarConfig -> {
+ mSystemBarSidesByZOrder.add(systemBarConfig.getSide());
+ });
+ }
+
+ private static boolean isHorizontalBar(@SystemBarSide int side) {
+ return side == TOP || side == BOTTOM;
+ }
+
+ private static boolean isVerticalBar(@SystemBarSide int side) {
+ return side == LEFT || side == RIGHT;
+ }
+
+ private static final class SystemBarConfig {
+ private final int mSide;
+ private final int mBarType;
+ private final int mGirth;
+ private final int mZOrder;
+
+ private int[] mPaddings = new int[]{0, 0, 0, 0};
+
+ private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder) {
+ mSide = side;
+ mBarType = barType;
+ mGirth = girth;
+ mZOrder = zOrder;
+ }
+
+ private int getSide() {
+ return mSide;
+ }
+
+ private int getBarType() {
+ return mBarType;
+ }
+
+ private int getGirth() {
+ return mGirth;
+ }
+
+ private int getZOrder() {
+ return mZOrder;
+ }
+
+ private int[] getPaddings() {
+ return mPaddings;
+ }
+
+ private WindowManager.LayoutParams getLayoutParams() {
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ isHorizontalBar(mSide) ? ViewGroup.LayoutParams.MATCH_PARENT : mGirth,
+ isHorizontalBar(mSide) ? mGirth : ViewGroup.LayoutParams.MATCH_PARENT,
+ mapZOrderToBarType(mZOrder),
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+ PixelFormat.TRANSLUCENT);
+ lp.setTitle(BAR_TITLE_MAP.get(mSide));
+ lp.providesInsetsTypes = new int[]{BAR_TYPE_MAP[mBarType], BAR_GESTURE_MAP.get(mSide)};
+ lp.setFitInsetsTypes(0);
+ lp.windowAnimations = 0;
+ lp.gravity = BAR_GRAVITY_MAP.get(mSide);
+ return lp;
+ }
+
+ private int mapZOrderToBarType(int zOrder) {
+ return zOrder >= HUN_ZORDER ? WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL
+ : WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
+ }
+
+ private void setPaddingBySide(@SystemBarSide int side, int padding) {
+ mPaddings[side] = padding;
+ }
+ }
+
+ private static final class SystemBarConfigBuilder {
+ private int mSide;
+ private int mBarType;
+ private int mGirth;
+ private int mZOrder;
+
+ private SystemBarConfigBuilder setSide(@SystemBarSide int side) {
+ mSide = side;
+ return this;
+ }
+
+ private SystemBarConfigBuilder setBarType(int type) {
+ mBarType = type;
+ return this;
+ }
+
+ private SystemBarConfigBuilder setGirth(int girth) {
+ mGirth = girth;
+ return this;
+ }
+
+ private SystemBarConfigBuilder setZOrder(int zOrder) {
+ mZOrder = zOrder;
+ return this;
+ }
+
+ private SystemBarConfig build() {
+ return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder);
+ }
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
index aea691443290..7db2823dc3b9 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
@@ -16,12 +16,12 @@
package com.android.systemui.car.userswitcher;
-import android.app.ActivityManager;
import android.car.Car;
import android.car.user.CarUserManager;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.window.OverlayViewMediator;
@@ -36,13 +36,16 @@ public class UserSwitchTransitionViewMediator implements OverlayViewMediator,
private static final String TAG = "UserSwitchTransitionViewMediator";
private final CarServiceProvider mCarServiceProvider;
+ private final CarDeviceProvisionedController mCarDeviceProvisionedController;
private final UserSwitchTransitionViewController mUserSwitchTransitionViewController;
@Inject
public UserSwitchTransitionViewMediator(
CarServiceProvider carServiceProvider,
+ CarDeviceProvisionedController carDeviceProvisionedController,
UserSwitchTransitionViewController userSwitchTransitionViewController) {
mCarServiceProvider = carServiceProvider;
+ mCarDeviceProvisionedController = carDeviceProvisionedController;
mUserSwitchTransitionViewController = userSwitchTransitionViewController;
}
@@ -74,7 +77,7 @@ public class UserSwitchTransitionViewMediator implements OverlayViewMediator,
@VisibleForTesting
void handleUserLifecycleEvent(CarUserManager.UserLifecycleEvent event) {
if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING
- && ActivityManager.getCurrentUser() == event.getUserId()) {
+ && mCarDeviceProvisionedController.getCurrentUser() == event.getUserId()) {
mUserSwitchTransitionViewController.handleShow(event.getUserId());
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
index 5c80202ba592..e493c97a9b46 100644
--- a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
@@ -36,25 +36,20 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.TransactionPool;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/**
* Controller that maps between displays and {@link IDisplayWindowInsetsController} in order to
* give system bar control to SystemUI.
* {@link R.bool#config_remoteInsetsControllerControlsSystemBars} determines whether this controller
* takes control or not.
*/
-@Singleton
public class DisplaySystemBarsController extends DisplayImeController {
private static final String TAG = "DisplaySystemBarsController";
- private SparseArray<PerDisplay> mPerDisplaySparseArray;
private final Context mContext;
+ private SparseArray<PerDisplay> mPerDisplaySparseArray;
- @Inject
- public DisplaySystemBarsController(
+ private DisplaySystemBarsController(
Context context,
IWindowManager wmService,
DisplayController displayController,
@@ -172,4 +167,33 @@ public class DisplaySystemBarsController extends DisplayImeController {
}
}
}
+
+ /** Builds {@link DisplaySystemBarsController} instance. */
+ public static class Builder {
+ private Context mContext;
+ private IWindowManager mWmService;
+ private DisplayController mDisplayController;
+ private Handler mHandler;
+ private TransactionPool mTransactionPool;
+
+ public Builder(Context context, IWindowManager wmService,
+ DisplayController displayController, Handler handler,
+ TransactionPool transactionPool) {
+ mContext = context;
+ mWmService = wmService;
+ mDisplayController = displayController;
+ mHandler = handler;
+ mTransactionPool = transactionPool;
+ }
+
+ /** Builds and initializes {@link DisplaySystemBarsController} instance. */
+ public DisplaySystemBarsController build() {
+ DisplaySystemBarsController displaySystemBarsController =
+ new DisplaySystemBarsController(
+ mContext, mWmService, mDisplayController, mHandler, mTransactionPool);
+ // Separates startMonitorDisplays from constructor to prevent circular init issue.
+ displaySystemBarsController.startMonitorDisplays();
+ return displaySystemBarsController;
+ }
+ }
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
index dec8b8ecdfb4..0b164a2e1a51 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
@@ -73,7 +73,8 @@ public class CarNavigationBarControllerTest extends SysuiTestCase {
private CarNavigationBarController createNavigationBarController() {
return new CarNavigationBarController(mContext, mNavigationBarViewFactory,
mButtonSelectionStateController, () -> mHvacController,
- mButtonRoleHolderController);
+ mButtonRoleHolderController,
+ new SystemBarConfigs(mTestableResources.getResources()));
}
@Test
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
index d9edfa960858..2b5af71dccaa 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
@@ -142,7 +142,7 @@ public class CarNavigationBarTest extends SysuiTestCase {
mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext),
mAutoHideController, mButtonSelectionStateListener, mHandler, mUiBgExecutor,
mBarService, () -> mKeyguardStateController, () -> mIconPolicy,
- () -> mIconController);
+ () -> mIconController, new SystemBarConfigs(mTestableResources.getResources()));
}
@Test
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
new file mode 100644
index 000000000000..8b1589913d1d
--- /dev/null
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.systemui.car.navigationbar;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.car.CarSystemUiTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@CarSystemUiTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class SystemBarConfigsTest extends SysuiTestCase {
+
+ private SystemBarConfigs mSystemBarConfigs;
+ @Mock
+ private Resources mResources;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ setDefaultValidConfig();
+ }
+
+ @Test
+ public void onInit_allSystemBarsEnabled_eachHasUniqueBarTypes_doesNotThrowException() {
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void onInit_allSystemBarsEnabled_twoBarsHaveDuplicateType_throwsRuntimeException() {
+ when(mResources.getInteger(R.integer.config_topSystemBarType)).thenReturn(0);
+ when(mResources.getInteger(R.integer.config_bottomSystemBarType)).thenReturn(0);
+
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ }
+
+ @Test
+ public void onInit_allSystemBarsEnabled_systemBarSidesSortedByZOrder() {
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ List<Integer> actualOrder = mSystemBarConfigs.getSystemBarSidesByZOrder();
+ List<Integer> expectedOrder = new ArrayList<>();
+ expectedOrder.add(SystemBarConfigs.LEFT);
+ expectedOrder.add(SystemBarConfigs.RIGHT);
+ expectedOrder.add(SystemBarConfigs.TOP);
+ expectedOrder.add(SystemBarConfigs.BOTTOM);
+
+ assertTrue(actualOrder.equals(expectedOrder));
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void onInit_intersectingBarsHaveSameZOrder_throwsRuntimeException() {
+ when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(33);
+ when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(33);
+
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ }
+
+ @Test
+ public void getTopSystemBarLayoutParams_topBarEnabled_returnsTopSystemBarLayoutParams() {
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
+ SystemBarConfigs.TOP);
+
+ assertNotNull(lp);
+ }
+
+ @Test
+ public void getTopSystemBarLayoutParams_topBarNotEnabled_returnsNull() {
+ when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false);
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
+ SystemBarConfigs.TOP);
+
+ assertNull(lp);
+ }
+
+ @Test
+ public void topSystemBarHasHigherZOrderThanHuns_topSystemBarIsNavigationBarPanelType() {
+ when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(
+ SystemBarConfigs.getHunZOrder() + 1);
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
+ SystemBarConfigs.TOP);
+
+ assertEquals(lp.type, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL);
+ }
+
+ @Test
+ public void topSystemBarHasLowerZOrderThanHuns_topSystemBarIsStatusBarAdditionalType() {
+ when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(
+ SystemBarConfigs.getHunZOrder() - 1);
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
+ SystemBarConfigs.TOP);
+
+ assertEquals(lp.type, WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL);
+ }
+
+ // Set valid config where all system bars are enabled.
+ private void setDefaultValidConfig() {
+ when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(true);
+ when(mResources.getBoolean(R.bool.config_enableBottomNavigationBar)).thenReturn(true);
+ when(mResources.getBoolean(R.bool.config_enableLeftNavigationBar)).thenReturn(true);
+ when(mResources.getBoolean(R.bool.config_enableRightNavigationBar)).thenReturn(true);
+
+ when(mResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height)).thenReturn(100);
+ when(mResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height)).thenReturn(100);
+ when(mResources.getDimensionPixelSize(R.dimen.car_left_navigation_bar_width)).thenReturn(
+ 100);
+ when(mResources.getDimensionPixelSize(R.dimen.car_right_navigation_bar_width)).thenReturn(
+ 100);
+
+ when(mResources.getInteger(R.integer.config_topSystemBarType)).thenReturn(0);
+ when(mResources.getInteger(R.integer.config_bottomSystemBarType)).thenReturn(1);
+ when(mResources.getInteger(R.integer.config_leftSystemBarType)).thenReturn(2);
+ when(mResources.getInteger(R.integer.config_rightSystemBarType)).thenReturn(3);
+
+ when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(5);
+ when(mResources.getInteger(R.integer.config_bottomSystemBarZOrder)).thenReturn(10);
+ when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(2);
+ when(mResources.getInteger(R.integer.config_rightSystemBarZOrder)).thenReturn(3);
+ }
+}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
index 20576e9ec11f..67f222b9e29a 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
@@ -220,7 +220,7 @@ public class SideLoadedAppListenerTest extends SysuiTestCase {
verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display1);
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(display2);
+ verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display2);
verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display3);
verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(display1);
verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display2);
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
index de6feb64391f..7aeffce7042d 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.car.userswitcher;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -24,6 +25,8 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.CarSystemUiTest;
@@ -37,13 +40,15 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
-public class UserSwitchTransitionViewMediatorTest {
+public class UserSwitchTransitionViewMediatorTest extends SysuiTestCase {
private static final int TEST_USER = 100;
private UserSwitchTransitionViewMediator mUserSwitchTransitionViewMediator;
@Mock
private CarServiceProvider mCarServiceProvider;
@Mock
+ private CarDeviceProvisionedController mCarDeviceProvisionedController;
+ @Mock
private UserSwitchTransitionViewController mUserSwitchTransitionViewController;
@Mock
private CarUserManager.UserLifecycleEvent mUserLifecycleEvent;
@@ -53,21 +58,35 @@ public class UserSwitchTransitionViewMediatorTest {
MockitoAnnotations.initMocks(this);
mUserSwitchTransitionViewMediator = new UserSwitchTransitionViewMediator(
- mCarServiceProvider, mUserSwitchTransitionViewController);
-
+ mCarServiceProvider, mCarDeviceProvisionedController,
+ mUserSwitchTransitionViewController);
+ when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(TEST_USER);
}
@Test
- public void onUserLifecycleEvent_userStarting_callsHandleShow() {
+ public void onUserLifecycleEvent_userStarting_isCurrentUser_callsHandleShow() {
when(mUserLifecycleEvent.getEventType()).thenReturn(
CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
+
mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
verify(mUserSwitchTransitionViewController).handleShow(TEST_USER);
}
@Test
+ public void onUserLifecycleEvent_userStarting_isNotCurrentUser_doesNotCallHandleShow() {
+ when(mUserLifecycleEvent.getEventType()).thenReturn(
+ CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
+ when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
+ when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(TEST_USER + 1);
+
+ mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
+
+ verify(mUserSwitchTransitionViewController, never()).handleShow(TEST_USER);
+ }
+
+ @Test
public void onUserLifecycleEvent_userSwitching_callsHandleHide() {
when(mUserLifecycleEvent.getEventType()).thenReturn(
CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING);
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
index 391f75e35382..b65578dbe02c 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
@@ -64,13 +64,13 @@ public class DisplaySystemBarsControllerTest extends SysuiTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
- mController = new DisplaySystemBarsController(
+ mController = new DisplaySystemBarsController.Builder(
mContext,
mIWindowManager,
mDisplayController,
mHandler,
mTransactionPool
- );
+ ).build();
}
@Test
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index bcaee367b03c..f108e06951ef 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -259,18 +259,19 @@ public class DeviceDiscoveryService extends Service {
private void onDeviceFound(@Nullable DeviceFilterPair device) {
if (device == null) return;
- if (mDevicesFound.contains(device)) {
- return;
- }
-
- if (DEBUG) Log.i(LOG_TAG, "Found device " + device);
-
Handler.getMain().sendMessage(obtainMessage(
DeviceDiscoveryService::onDeviceFoundMainThread, this, device));
}
@MainThread
void onDeviceFoundMainThread(@NonNull DeviceFilterPair device) {
+ if (mDevicesFound.contains(device)) {
+ Log.i(LOG_TAG, "Skipping device " + device + " - already among found devices");
+ return;
+ }
+
+ Log.i(LOG_TAG, "Found device " + device);
+
if (mDevicesFound.isEmpty()) {
onReadyToShowUI();
}
@@ -428,10 +429,10 @@ public class DeviceDiscoveryService extends Service {
@Override
public String toString() {
- return "DeviceFilterPair{" +
- "device=" + device +
- ", filter=" + filter +
- '}';
+ return "DeviceFilterPair{"
+ + "device=" + device + " " + getDisplayName()
+ + ", filter=" + filter
+ + '}';
}
}
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java
index 276d55ee9a5e..9fe7ab655e46 100644
--- a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java
@@ -26,7 +26,7 @@ import android.os.Message;
import android.view.View;
/**
- * Dummy view to emulate stuff an OEM may want to do.
+ * Fake view to emulate stuff an OEM may want to do.
*/
public class FakeView extends View {
static final long TICK_DELAY = 30*1000; // 30 seconds
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 1b5062efa23e..01d7682416fa 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -42,10 +42,10 @@
<string name="connected_via_app" msgid="3532267661404276584">"Падключана праз праграму \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="available_via_passpoint" msgid="1716000261192603682">"Даступна праз %1$s"</string>
<string name="tap_to_sign_up" msgid="5356397741063740395">"Націсніце, каб зарэгістравацца"</string>
- <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Не падключана да інтэрнэту"</string>
+ <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Няма падключэння да інтэрнэту"</string>
<string name="private_dns_broken" msgid="1984159464346556931">"Не ўдалося атрымаць доступ да прыватнага DNS-сервера"</string>
<string name="wifi_limited_connection" msgid="1184778285475204682">"Абмежаваныя магчымасці падключэння"</string>
- <string name="wifi_status_no_internet" msgid="3799933875988829048">"Не падключана да інтэрнэту"</string>
+ <string name="wifi_status_no_internet" msgid="3799933875988829048">"Няма падключэння да інтэрнэту"</string>
<string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Трэба выканаць уваход"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Пункт доступу часова заняты"</string>
<string name="connected_via_carrier" msgid="1968057009076191514">"Падключана праз %1$s"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 8e8368f9bc62..03161d051342 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -659,9 +659,6 @@
<!-- Setting Checkbox title for enabling Bluetooth Gabeldorsche. [CHAR LIMIT=40] -->
<string name="bluetooth_enable_gabeldorsche">Enable Gabeldorsche</string>
- <!-- Setting Checkbox title for enabling Enhanced Connectivity [CHAR LIMIT=80] -->
- <string name="enhanced_connectivity">Enhanced Connectivity</string>
-
<!-- UI debug setting: Select Bluetooth AVRCP Version -->
<string name="bluetooth_select_avrcp_version_string">Bluetooth AVRCP Version</string>
<!-- UI debug setting: Select Bluetooth AVRCP Version -->
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 18c2957b1adc..4eea8ad92e61 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -112,7 +112,6 @@ public class SecureSettings {
Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
Settings.Secure.VR_DISPLAY_MODE,
Settings.Secure.NOTIFICATION_BADGING,
- Settings.Secure.NOTIFICATION_FEEDBACK_ENABLED,
Settings.Secure.NOTIFICATION_DISMISS_RTL,
Settings.Secure.QS_AUTO_ADDED_TILES,
Settings.Secure.SCREENSAVER_ENABLED,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index dd94d2eb8fe0..a02d67fd7bca 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -149,5 +149,6 @@ public class GlobalSettingsValidators {
VALIDATORS.put(Global.CUSTOM_BUGREPORT_HANDLER_APP, ANY_STRING_VALIDATOR);
VALIDATORS.put(Global.CUSTOM_BUGREPORT_HANDLER_USER, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Global.DEVELOPMENT_SETTINGS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.NOTIFICATION_FEEDBACK_ENABLED, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 91f3f4af0566..c68ddbdcb5ad 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -189,7 +189,6 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SHOW_NOTIFICATION_SNOOZE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NOTIFICATION_HISTORY_ENABLED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Secure.NOTIFICATION_FEEDBACK_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ZEN_DURATION, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SHOW_ZEN_SETTINGS_SUGGESTION, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index df0137d8179e..fa06e14acccb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -761,8 +761,8 @@ class SettingsProtoDumpUtil {
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
GlobalSettingsProto.Gpu.ANGLE_GL_DRIVER_SELECTION_VALUES);
dumpSetting(s, p,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST,
- GlobalSettingsProto.Gpu.ANGLE_WHITELIST);
+ Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST,
+ GlobalSettingsProto.Gpu.ANGLE_ALLOWLIST);
dumpSetting(s, p,
Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX,
GlobalSettingsProto.Gpu.SHOW_ANGLE_IN_USE_DIALOG);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java
index 6e5b8890438d..66aa7baa3b51 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java
@@ -35,19 +35,17 @@ import java.util.List;
public class WriteFallbackSettingsFilesJobService extends JobService {
@Override
public boolean onStartJob(final JobParameters params) {
- switch (params.getJobId()) {
- case WRITE_FALLBACK_SETTINGS_FILES_JOB_ID:
- final List<String> settingsFiles = new ArrayList<>();
- settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_SECURE, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_SSAID, ""));
- settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, ""));
- SettingsProvider.writeFallBackSettingsFiles(settingsFiles);
- return true;
- default:
- return false;
+ if (params.getJobId() != WRITE_FALLBACK_SETTINGS_FILES_JOB_ID) {
+ return false;
}
+ final List<String> settingsFiles = new ArrayList<>();
+ settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_SECURE, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_SSAID, ""));
+ settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, ""));
+ SettingsProvider.writeFallBackSettingsFiles(settingsFiles);
+ return false;
}
@Override
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 5d77a2a85d86..4bb8f45f331f 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -270,7 +270,6 @@ public class SettingsBackupTest {
Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
Settings.Global.SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS,
Settings.Global.ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT,
- Settings.Global.ENHANCED_CONNECTIVITY_ENABLED,
Settings.Global.ENHANCED_4G_MODE_ENABLED,
Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
Settings.Global.ERROR_LOGCAT_PREFIX,
@@ -390,6 +389,7 @@ public class SettingsBackupTest {
Settings.Global.NITZ_UPDATE_DIFF,
Settings.Global.NITZ_UPDATE_SPACING,
Settings.Global.NOTIFICATION_SNOOZE_OPTIONS,
+ Settings.Global.NOTIFICATION_FEEDBACK_ENABLED,
Settings.Global.NR_NSA_TRACKING_SCREEN_OFF_MODE,
Settings.Global.NSD_ON,
Settings.Global.NTP_SERVER,
@@ -503,7 +503,7 @@ public class SettingsBackupTest {
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE,
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS,
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST,
+ Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST,
Settings.Global.GAME_DRIVER_ALL_APPS,
Settings.Global.GAME_DRIVER_OPT_IN_APPS,
Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
diff --git a/packages/SimAppDialog/Android.bp b/packages/SimAppDialog/Android.bp
index ff26710fa2e1..176035f73b65 100644
--- a/packages/SimAppDialog/Android.bp
+++ b/packages/SimAppDialog/Android.bp
@@ -4,7 +4,6 @@ android_app {
srcs: ["src/**/*.java"],
platform_apis: true,
- certificate: "platform",
static_libs: [
"androidx.legacy_legacy-support-v4",
diff --git a/packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png b/packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png
new file mode 100644
index 000000000000..6c1f1cfdea7c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/one_handed_tutorial.png b/packages/SystemUI/res/drawable-mdpi/one_handed_tutorial.png
new file mode 100644
index 000000000000..6983c3b880c9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/one_handed_tutorial.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/one_handed_tutorial.png b/packages/SystemUI/res/drawable-xhdpi/one_handed_tutorial.png
new file mode 100644
index 000000000000..3ff692f0c6fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/one_handed_tutorial.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/one_handed_tutorial.png b/packages/SystemUI/res/drawable-xxhdpi/one_handed_tutorial.png
new file mode 100644
index 000000000000..75723fb2ea5a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/one_handed_tutorial.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/one_handed_tutorial.png b/packages/SystemUI/res/drawable-xxxhdpi/one_handed_tutorial.png
new file mode 100644
index 000000000000..173abedae48a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/one_handed_tutorial.png
Binary files differ
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e48fe656d187..308fd88ee6cd 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Instellings"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Het dit"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Stort SysUI-hoop"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> gebruik tans jou <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programme gebruik tans jou <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ligging"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors is af"</string>
<string name="device_services" msgid="1549944177856658705">"Toesteldienste"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Titelloos"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 300ca0e5b141..f2bf5778b42f 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ቅንብሮች"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ገባኝ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI Heap አራግፍ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> የእርስዎን <xliff:g id="TYPES_LIST">%2$s</xliff:g> እየተጠቀመ ነው።"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"መተግበሪያዎች የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> እየተጠቀሙ ነው።"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"፣ "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" እና "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ካሜራ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"አካባቢ"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"ማይክሮፎን"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ዳሳሾች ጠፍተዋል"</string>
<string name="device_services" msgid="1549944177856658705">"የመሣሪያ አገልግሎቶች"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ርዕስ የለም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 7f2a405efed2..36280e716c4e 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1005,6 +1005,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"الإعدادات"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"حسنًا"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"‏تفريغ ذاكرة SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"التطبيق <xliff:g id="APP">%1$s</xliff:g> يستخدم <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"تستخدم التطبيقات <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"الكاميرا"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"الموقع"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"الميكروفون"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"إيقاف أجهزة الاستشعار"</string>
<string name="device_services" msgid="1549944177856658705">"خدمات الأجهزة"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"بلا عنوان"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 0345af07cd91..a4cc17b822d5 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ছেটিংবোৰ"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"বুজি পালোঁ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI হীপ ডাম্প কৰক"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"এপ্লিকেশ্বনসমূহে আপোনাৰ <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" আৰু "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"কেমেৰা"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"অৱস্থান"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্ৰ\'ফ\'ন"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ছেন্সৰ অফ হৈ আছে"</string>
<string name="device_services" msgid="1549944177856658705">"ডিভাইচ সেৱা"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"কোনো শিৰোনাম নাই"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index d0025306d203..9443ba8ac22c 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ayarlar"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Anladım"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> tətbiqlərindən istifadə edir."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Tətbiqlər <xliff:g id="TYPES_LIST">%s</xliff:g> istifadə edir."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" və "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"məkan"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorlar deaktivdir"</string>
<string name="device_services" msgid="1549944177856658705">"Cihaz Xidmətləri"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Başlıq yoxdur"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 5cca958bbe96..5b8c44599eed 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -990,6 +990,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Podešavanja"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Važi"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori su isključeni"</string>
<string name="device_services" msgid="1549944177856658705">"Usluge za uređaje"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 956ef477c927..6ee51682fe85 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -919,7 +919,7 @@
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрыць хуткія налады."</string>
<string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Будзільнік пастаўлены."</string>
<string name="accessibility_quick_settings_user" msgid="505821942882668619">"Вы ўвайшлі як <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="data_connection_no_internet" msgid="691058178914184544">"Не падключана да інтэрнэту"</string>
+ <string name="data_connection_no_internet" msgid="691058178914184544">"Няма падключэння да інтэрнэту"</string>
<string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"Паказаць падрабязную інфармацыю."</string>
<string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"Прычына недаступнасці: <xliff:g id="REASON">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Адкрыць налады <xliff:g id="ID_1">%s</xliff:g>."</string>
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Налады"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Зразумела"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Праграма \"<xliff:g id="APP">%1$s</xliff:g>\" выкарыстоўвае: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Праграмы выкарыстоўваюць: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"геалакацыя"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"мікрафон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчыкі выкл."</string>
<string name="device_services" msgid="1549944177856658705">"Сэрвісы прылады"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Без назвы"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index d0836e4509fe..c7bb3d08579c 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Настройки"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Разбрах"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> използва <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Някои приложения използват <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камерата"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"местополож."</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофона"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Сензорите са изключени"</string>
<string name="device_services" msgid="1549944177856658705">"Услуги за устройството"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index a584955b534d..42e7523aef81 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"সেটিংস"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"বুঝেছি"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> আপনার <xliff:g id="TYPES_LIST">%2$s</xliff:g> ব্যবহার করছে।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"অ্যাপ্লিকেশনগুলি আপনার <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যবহার করছে।"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" এবং "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ক্যামেরা"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"লোকেশন"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্রোফোন"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"সেন্সর বন্ধ"</string>
<string name="device_services" msgid="1549944177856658705">"ডিভাইস সংক্রান্ত পরিষেবা"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"কোনও শীর্ষক নেই"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 4c872d22054f..16a1aa615c9b 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -990,6 +990,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Postavke"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Razumijem"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori su isključeni"</string>
<string name="device_services" msgid="1549944177856658705">"Usluge uređaja"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 7267c31b1f36..fdcec987f438 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Configuració"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Entesos"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Aboca espai de SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> està fent servir el següent: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"càmera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ubicació"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"micròfon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors desactivats"</string>
<string name="device_services" msgid="1549944177856658705">"Serveis per a dispositius"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sense títol"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 29b5281f689f..ab3b4fb2659c 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Nastavení"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Rozumím"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Výpis haldy SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Aplikace <xliff:g id="APP">%1$s</xliff:g> využívá tato oprávnění: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikace využívají tato oprávnění: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzory jsou vypnuty"</string>
<string name="device_services" msgid="1549944177856658705">"Služby zařízení"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index dff770d49e28..0fc9b9495388 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Indstillinger"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Gem SysUI-heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> anvender enhedens <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps anvender enhedens <xliff:g id="TYPES_LIST">%s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"placering"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Deaktiver sensorer"</string>
<string name="device_services" msgid="1549944177856658705">"Enhedstjenester"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 52275fcd637e..a6b137a8e9e5 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Einstellungen"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ok"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> verwendet gerade Folgendes: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps verwenden gerade Folgendes: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" und "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"Kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"Standort"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"Mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensoren aus"</string>
<string name="device_services" msgid="1549944177856658705">"Gerätedienste"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Kein Titel"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index bf4c61994c29..bdd19a18b2dd 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ρυθμίσεις"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Το κατάλαβα"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Στιγμ. μνήμης SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> χρησιμοποιεί τις λειτουργίες <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Οι εφαρμογές χρησιμοποιούν τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" και "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"κάμερα"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"τοποθεσία"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"μικρόφωνο"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Αισθητήρες ανενεργοί"</string>
<string name="device_services" msgid="1549944177856658705">"Υπηρεσίες συσκευής"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Χωρίς τίτλο"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index acb811107463..68a8d30477f6 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Settings"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string>
<string name="device_services" msgid="1549944177856658705">"Device Services"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index e3bad1f83a90..e9856af6cb1e 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Settings"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string>
<string name="device_services" msgid="1549944177856658705">"Device Services"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index acb811107463..68a8d30477f6 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Settings"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string>
<string name="device_services" msgid="1549944177856658705">"Device Services"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index acb811107463..68a8d30477f6 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Settings"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensors off"</string>
<string name="device_services" msgid="1549944177856658705">"Device Services"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 25ec6c384157..eacef2624b05 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎Settings‎‏‎‎‏‎"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎Got it‎‏‎‎‏‎"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎Dump SysUI Heap‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is using your ‎‏‎‎‏‏‎<xliff:g id="TYPES_LIST">%2$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎Applications are using your ‎‏‎‎‏‏‎<xliff:g id="TYPES_LIST">%s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎, ‎‏‎‎‏‎ "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‎ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎camera‎‏‎‎‏‎"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎location‎‏‎‎‏‎"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎microphone‎‏‎‎‏‎"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎Sensors off‎‏‎‎‏‎"</string>
<string name="device_services" msgid="1549944177856658705">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎Device Services‎‏‎‎‏‎"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎No title‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 01bed104a951..94a464bb6afa 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Configuración"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Entendido"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar pila de SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que están usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Se desactivaron los sensores"</string>
<string name="device_services" msgid="1549944177856658705">"Servicios del dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 67678d24a0a6..0e7d376e5884 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ajustes"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Entendido"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar pila de SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desactivados"</string>
<string name="device_services" msgid="1549944177856658705">"Servicios del dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index a46fa490b4a8..fc9c73bb10bf 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Seaded"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Selge"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> kasutab järgmisi: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Rakendused kasutavad järgmisi: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kaamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"asukoht"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Andurid on välja lülitatud"</string>
<string name="device_services" msgid="1549944177856658705">"Seadme teenused"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Pealkiri puudub"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 19fc4f50d0d3..041beab2e74c 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ezarpenak"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ados"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> erabiltzen ari da."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" eta "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"kokapena"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonoa"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sentsoreak desaktibatuta daude"</string>
<string name="device_services" msgid="1549944177856658705">"Gailuetarako zerbitzuak"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Ez du izenik"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b8c87938d423..05e076f55a12 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"تنظیمات"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"متوجه شدم"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> از <xliff:g id="TYPES_LIST">%2$s</xliff:g> شما استفاده می‌کند."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"برنامه‌ها از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده می‌‌کنند."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"دوربین"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"مکان"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"میکروفون"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"حسگرها خاموش است"</string>
<string name="device_services" msgid="1549944177856658705">"سرویس‌های دستگاه"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"بدون عنوان"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 44a66c31b954..4fccaaca57f2 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Asetukset"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Selvä"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Luo SysUI-keon vedos"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> käyttää ominaisuuksia (<xliff:g id="TYPES_LIST">%2$s</xliff:g>)."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> ovat sovellusten käytössä."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"sijainti"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoni"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Anturit pois päältä"</string>
<string name="device_services" msgid="1549944177856658705">"Laitepalvelut"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Ei nimeä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 15cf6eb40658..4e2074c34a88 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Paramètres"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Copier mémoire SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"position"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Capteurs désactivés"</string>
<string name="device_services" msgid="1549944177856658705">"Services de l\'appareil"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 784186b013a9..fedec563edcf 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Paramètres"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Copier mémoire SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"position"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"micro"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Capteurs désactivés"</string>
<string name="device_services" msgid="1549944177856658705">"Services pour l\'appareil"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
@@ -1021,9 +1028,9 @@
<string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Paramètres"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Fenêtre des commandes d\'agrandissement"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Commandes de contrôle des appareils"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajouter des commandes pour vos appareils connectés"</string>
- <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes de contrôle des appareils"</string>
+ <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Appuyez de manière prolongée sur le bouton Marche/Arrêt pour accéder aux commandes"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string>
<plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
@@ -1046,7 +1053,7 @@
<string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'application <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres n\'ont pas changé."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"Commandes compatibles indisponibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string>
- <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes de contrôle des appareils"</string>
+ <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes des appareils"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggérée par <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_dialog_confirmation" msgid="586517302736263447">"Commandes mises à jour"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index c732c7bbff1f..c1b9024e8b44 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Configuración"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"De acordo"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Baleirado mem. SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> está utilizando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hai aplicacións que están utilizando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"a cámara"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"a localiz."</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"o micrófono"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Desactivar sensores"</string>
<string name="device_services" msgid="1549944177856658705">"Servizos do dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sen título"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 5d3d3af8f917..9c2f71790fb0 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"સેટિંગ"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"સમજાઈ ગયું"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ઍપ તમારા <xliff:g id="TYPES_LIST">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ઍપ્લિકેશન તમારા <xliff:g id="TYPES_LIST">%s</xliff:g>નો ઉપયોગ કરી રહી છે."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" અને "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"કૅમેરા"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"સ્થાન"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"માઇક્રોફોન"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"સેન્સર બંધ છે"</string>
<string name="device_services" msgid="1549944177856658705">"ડિવાઇસ સેવાઓ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f6bc4cdab087..cc2faa2a598c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -987,6 +987,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"सेटिंग"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ठीक है"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> आपकी <xliff:g id="TYPES_LIST">%2$s</xliff:g> का इस्तेमाल कर रहा है."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ऐप्लिकेशन आपकी <xliff:g id="TYPES_LIST">%s</xliff:g> का इस्तेमाल कर रहे हैं."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" और "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"कैमरा"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"जगह"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफ़ोन"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"सेंसर बंद हैं"</string>
<string name="device_services" msgid="1549944177856658705">"डिवाइस सेवाएं"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"कोई शीर्षक नहीं"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index bfd5aa001c24..90251995002d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -990,6 +990,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Postavke"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Shvaćam"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji mem. SysUI-a"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> upotrebljava <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori su isključeni"</string>
<string name="device_services" msgid="1549944177856658705">"Usluge uređaja"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c8f4a467f94b..689d86960c88 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Beállítások"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Értem"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI-memória-kiírás"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"A(z) <xliff:g id="APP">%1$s</xliff:g> használja a következőket: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Több alkalmazás használja a következőket: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" és "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"helyadatok"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Érzékelők kikapcsolva"</string>
<string name="device_services" msgid="1549944177856658705">"Eszközszolgáltatások"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Nincs cím"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 53286188af47..a574f26a514d 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -916,7 +916,7 @@
<string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Խմբագրել կարգավորումների հերթականությունը:"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Կողպէկրան"</string>
- <string name="thermal_shutdown_title" msgid="2702966892682930264">"Հեռախոսն անջատվել է տաքանալու պատճառով"</string>
+ <string name="thermal_shutdown_title" msgid="2702966892682930264">"Հեռախոսն անջատվել էր տաքանալու պատճառով"</string>
<string name="thermal_shutdown_message" msgid="6142269839066172984">"Հեռախոսն այժմ նորմալ է աշխատում։\nՀպեք՝ ավելին իմանալու համար։"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ձեր հեռախոսը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար: Հեռախոսն այժմ նորմալ աշխատում է:\n\nՀեռախոսը կարող է տաքանալ, եթե՝\n • Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավարկման հավելվածներ)\n • Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n • Օգտագործում եք ձեր հեռախոսը բարձր ջերմային պայմաններում"</string>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Քայլեր գերտաքացման ահազանգի դեպքում"</string>
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Կարգավորումներ"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Եղավ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն օգտագործում է ձեր <xliff:g id="TYPES_LIST">%2$s</xliff:g>:"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Հավելվածներն օգտագործում են ձեր <xliff:g id="TYPES_LIST">%s</xliff:g>:"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" և "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"տեսախցիկը"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"վայրը"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"խոսափողը"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Տվիչներն անջատած են"</string>
<string name="device_services" msgid="1549944177856658705">"Սարքի ծառայություններ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Անանուն"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index dfed57b94c51..7cc1b898dedb 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Setelan"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Oke"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Hapus Heap SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> menggunakan <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensor nonaktif"</string>
<string name="device_services" msgid="1549944177856658705">"Layanan Perangkat"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Tanpa judul"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 57cdb272f176..8b686b8deb96 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Stillingar"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ég skil"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Vista SysUI-gögn"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> er að nota <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Forrit eru að nota <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"myndavél"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"staðsetning"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"hljóðnemi"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Slökkt á skynjurum"</string>
<string name="device_services" msgid="1549944177856658705">"Tækjaþjónusta"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Enginn titill"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 679eb551e7f0..35742fd4d4db 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Impostazioni"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Esegui dump heap SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"L\'app <xliff:g id="APP">%1$s</xliff:g> sta usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Le app stanno usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"Fotocamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"luogo"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"un microfono"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensori disattivati"</string>
<string name="device_services" msgid="1549944177856658705">"Servizi del dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b6a723f00024..1029bb2042db 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"הגדרות"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"הבנתי"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"‏ערימת Dump SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> משתמשת ב<xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"אפליקציות משתמשות ב<xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" וגם "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"מצלמה"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"מיקום"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"מיקרופון"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"החיישנים כבויים"</string>
<string name="device_services" msgid="1549944177856658705">"שירותים למכשיר"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ללא שם"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b70e2e2bc14f..fedd9bb7ffc0 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"設定"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ヒープのダンプ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g>は<xliff:g id="TYPES_LIST">%2$s</xliff:g>を使用しています。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"アプリは<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しています。"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 、 "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"カメラ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"現在地情報"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"マイク"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"センサー OFF"</string>
<string name="device_services" msgid="1549944177856658705">"デバイス サービス"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"タイトルなし"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 0dda483b9d16..5c55112ea1fd 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"პარამეტრები"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"გასაგებია"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI გროვის გამოტანა"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g>-ის მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"აპლიკაციების მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" და "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"კამერა"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"მდებარეობა"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"მიკროფონი"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"სენსორების გამორთვა"</string>
<string name="device_services" msgid="1549944177856658705">"მოწყობილობის სერვისები"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"უსათაურო"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 27bc3ab4aab0..94c8ea33a461 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Параметрлер"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Түсінікті"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> қолданбасында <xliff:g id="TYPES_LIST">%2$s</xliff:g> пайдалануда."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" және "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"геодерек"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчиктер өшірулі"</string>
<string name="device_services" msgid="1549944177856658705">"Құрылғы қызметтері"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Атауы жоқ"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 36d5aa8ab45b..5ba460adebf3 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ការកំណត់"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"យល់ហើយ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"ចម្លង SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="TYPES_LIST">%2$s</xliff:g> របស់អ្នក។"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"កម្មវិធី​កំពុងប្រើ <xliff:g id="TYPES_LIST">%s</xliff:g> របស់អ្នក។"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" និង "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"កាមេរ៉ា"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ទីតាំង"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"មីក្រូហ្វូន"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"បិទឧបករណ៍​ចាប់សញ្ញា"</string>
<string name="device_services" msgid="1549944177856658705">"សេវាកម្មឧបករណ៍"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"គ្មាន​ចំណងជើង"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 2034472d18cd..7b8ed88bfd19 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ಅರ್ಥವಾಯಿತು"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ಅನ್ನು <xliff:g id="APP">%1$s</xliff:g> ಬಳಸುತ್ತಿದೆ."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಆ್ಯಪ್‌ಗಳು ಬಳಸುತ್ತಿವೆ."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ಮತ್ತು "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ಕ್ಯಾಮರಾ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ಸ್ಥಳ"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"ಮೈಕ್ರೋಫೋನ್‌"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ಸೆನ್ಸರ್‌ಗಳು ಆಫ್"</string>
<string name="device_services" msgid="1549944177856658705">"ಸಾಧನ ಸೇವೆಗಳು"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ef4a5f63d0d3..8d1177bec0ea 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"설정"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"확인"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g>이(가) <xliff:g id="TYPES_LIST">%2$s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"애플리케이션이 <xliff:g id="TYPES_LIST">%s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 및 "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"카메라"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"위치"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"마이크"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"센서 사용 안함"</string>
<string name="device_services" msgid="1549944177856658705">"기기 서비스"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"제목 없음"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index cfd91b56ddf5..794de98420d1 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Жөндөөлөр"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Түшүндүм"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> төмөнкүлөрдү колдонуп жатат: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Колдонмолор төмөнкүлөрдү пайдаланып жатышат: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" жана "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"жайгашкан жер"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Сенсорлорду өчүрүү"</string>
<string name="device_services" msgid="1549944177856658705">"Түзмөк кызматтары"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 90b5ad2267ac..2fe3f8075dbb 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ການຕັ້ງຄ່າ"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ເຂົ້າໃຈແລ້ວ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ຂອງທ່ານ."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ແອັບພລິເຄຊັນກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%s</xliff:g> ຂອງທ່ານ."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ແລະ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ກ້ອງຖ່າຍຮູບ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ສະຖານທີ່"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"ໄມໂຄຣໂຟນ"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ປິດການຮັບຮູ້ຢູ່"</string>
<string name="device_services" msgid="1549944177856658705">"ບໍລິການອຸປະກອນ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ບໍ່ມີຊື່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5c8e8d9ac8fb..4489b7dd62ee 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Nustatymai"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Supratau"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Pat. „SysUI“ krūvą"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ naudoja: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programos naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ir "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparatą"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"vietovę"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoną"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Jutikliai išjungti"</string>
<string name="device_services" msgid="1549944177856658705">"Įrenginio paslaugos"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Nėra pavadinimo"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index cbe076896d9f..d4826e42f17c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -28,15 +28,15 @@
<string name="battery_low_percent_format" msgid="4276661262843170964">"Atlikuši <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"Atlikušais laiks: <xliff:g id="PERCENTAGE">%1$s</xliff:g> — aptuveni <xliff:g id="TIME">%2$s</xliff:g> (ņemot vērā lietojumu)"</string>
<string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"Atlikušais laiks: <xliff:g id="PERCENTAGE">%1$s</xliff:g> — aptuveni <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"Atlikuši <xliff:g id="PERCENTAGE">%s</xliff:g>. Ir ieslēgts akumulatora jaudas taupīšanas režīms."</string>
+ <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"Atlikuši <xliff:g id="PERCENTAGE">%s</xliff:g>. Ir ieslēgts akumulatora enerģijas taupīšanas režīms."</string>
<string name="invalid_charger" msgid="4370074072117767416">"Nevar veikt uzlādi, izmantojot USB. Izmantojiet ierīces komplektācijā iekļauto uzlādes ierīci."</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Nevar veikt uzlādi, izmantojot USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Izmantojiet ierīces komplektācijā iekļauto uzlādes ierīci"</string>
<string name="battery_low_why" msgid="2056750982959359863">"Iestatījumi"</string>
- <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Vai ieslēgt akumulatora jaudas taupīšanas režīmu?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Par akumulatora jaudas taupīšanas režīmu"</string>
+ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Vai ieslēgt akumulatora enerģijas taupīšanas režīmu?"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Par akumulatora enerģijas taupīšanas režīmu"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ieslēgt"</string>
- <string name="battery_saver_start_action" msgid="4553256017945469937">"Ieslēgt akumulatora jaudas taupīšanas režīmu"</string>
+ <string name="battery_saver_start_action" msgid="4553256017945469937">"Ieslēgt akumulatora enerģijas taupīšanas režīmu"</string>
<string name="status_bar_settings_settings_button" msgid="534331565185171556">"Iestatījumi"</string>
<string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automātiska ekrāna pagriešana"</string>
@@ -423,7 +423,7 @@
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Plkst. <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Līdz <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tumšais motīvs"</string>
- <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Jaudas taupīšana"</string>
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Enerģijas taupīšana"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Saulrietā"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Līdz saullēktam"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Plkst. <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -502,9 +502,9 @@
<string name="user_remove_user_title" msgid="9124124694835811874">"Vai noņemt lietotāju?"</string>
<string name="user_remove_user_message" msgid="6702834122128031833">"Tiks dzēstas visas šī lietotāja lietotnes un dati."</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"Noņemt"</string>
- <string name="battery_saver_notification_title" msgid="8419266546034372562">"Akumulatora jaudas taupīšanas režīms ir ieslēgts"</string>
+ <string name="battery_saver_notification_title" msgid="8419266546034372562">"Akumulatora enerģijas taupīšanas režīms ir ieslēgts"</string>
<string name="battery_saver_notification_text" msgid="2617841636449016951">"Samazina veiktspēju un fona datus"</string>
- <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Izslēgt akumulatora jaudas taupīšanas režīmu"</string>
+ <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Izslēgt akumulatora enerģijas taupīšanas režīmu"</string>
<string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> iegūs piekļuvi visai informācijai, kas ierakstīšanas vai apraides laikā tiks rādīta jūsu ekrānā vai atskaņota jūsu ierīcē. Atļauja attiecas uz tādu informāciju kā paroles, maksājumu informācija, fotoattēli, ziņojumi un jūsu atskaņotais audio saturs."</string>
<string name="media_projection_dialog_service_text" msgid="958000992162214611">"Pakalpojums, kas nodrošina šo funkciju, iegūs piekļuvi visai informācijai, kas ierakstīšanas vai apraides laikā tiks rādīta jūsu ekrānā vai atskaņota jūsu ierīcē. Atļauja attiecas uz tādu informāciju kā paroles, maksājumu informācija, fotoattēli, ziņojumi un jūsu atskaņotais audio saturs."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Vai vēlaties sākt ierakstīšanu/apraidi?"</string>
@@ -780,8 +780,8 @@
<item quantity="other">%d minūtes</item>
</plurals>
<string name="battery_panel_title" msgid="5931157246673665963">"Akumulatora lietojums"</string>
- <string name="battery_detail_charging_summary" msgid="8821202155297559706">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
- <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akumulatora jaudas taupīšanas režīms"</string>
+ <string name="battery_detail_charging_summary" msgid="8821202155297559706">"Akumulatora enerģijas taupīšanas režīms uzlādes laikā nav pieejams."</string>
+ <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akumulatora enerģijas taupīšanas režīms"</string>
<string name="battery_detail_switch_summary" msgid="3668748557848025990">"Samazina veiktspēju un fona datus."</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"Poga <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_key_home" msgid="3734400625170020657">"Sākumvietas taustiņš"</string>
@@ -982,14 +982,21 @@
<string name="slice_permission_checkbox" msgid="4242888137592298523">"Atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> rādīt sadaļas no jebkuras lietotnes"</string>
<string name="slice_permission_allow" msgid="6340449521277951123">"Atļaut"</string>
<string name="slice_permission_deny" msgid="6870256451658176895">"Neatļaut"</string>
- <string name="auto_saver_title" msgid="6873691178754086596">"Pieskarieties, lai iestatītu akumulatora jaudas taupīšanas režīma grafiku"</string>
+ <string name="auto_saver_title" msgid="6873691178754086596">"Pieskarieties, lai iestatītu akumulatora enerģijas taupīšanas režīma grafiku"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"Ieslēgt, ja akumulators var izlādēties"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nē, paldies"</string>
<string name="auto_saver_enabled_title" msgid="4294726198280286333">"Ieslēgts akumulatora enerģijas taupīšanas režīma grafiks"</string>
- <string name="auto_saver_enabled_text" msgid="7889491183116752719">"Tiklīdz akumulatora uzlādes līmenis būs zemāks nekā <xliff:g id="PERCENTAGE">%d</xliff:g>%%, tiks automātiski ieslēgts akumulatora jaudas taupīšanas režīms."</string>
+ <string name="auto_saver_enabled_text" msgid="7889491183116752719">"Tiklīdz akumulatora uzlādes līmenis būs zemāks nekā <xliff:g id="PERCENTAGE">%d</xliff:g>%%, tiks automātiski ieslēgts akumulatora enerģijas taupīšanas režīms."</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"Iestatījumi"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Labi"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Lietotne <xliff:g id="APP">%1$s</xliff:g> izmanto funkcijas <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Lietojumprogrammas izmanto šādas funkcijas: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" un "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"atrašanās vieta"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofons"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensori izslēgti"</string>
<string name="device_services" msgid="1549944177856658705">"Ierīces pakalpojumi"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Nav nosaukuma"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5a000de3e843..4836ecf1574a 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Поставки"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Сфатив"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Извади SysUI-слика"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликациите користат <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"локација"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Сензорите се исклучени"</string>
<string name="device_services" msgid="1549944177856658705">"Услуги за уредот"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Без наслов"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 22392279a919..863ce1152752 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ക്രമീകരണം"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"മനസ്സിലായി"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ഉപയോഗിക്കുന്നു."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ആപ്പുകൾ നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%s</xliff:g> ഉപയോഗിക്കുന്നു."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" കൂടാതെ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ക്യാമറ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ലൊക്കേഷന്‍"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"മൈക്രോഫോൺ"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"സെൻസറുകൾ ഓഫാണ്"</string>
<string name="device_services" msgid="1549944177856658705">"ഉപകരണ സേവനങ്ങള്‍"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"പേരില്ല"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 8141ef3a1fc6..107c3101a221 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Тохиргоо"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ойлголоо"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> таны <xliff:g id="TYPES_LIST">%2$s</xliff:g>-г ашиглаж байна."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Аппууд таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" болон "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камер"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"байршил"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Мэдрэгчийг унтраах"</string>
<string name="device_services" msgid="1549944177856658705">"Төхөөрөмжийн үйлчилгээ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Гарчиггүй"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 79b7ae8b12a5..bd2c3a5d09e9 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"सेटिंग्ज"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"समजले"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI हीप डंप करा"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> तुमचे <xliff:g id="TYPES_LIST">%2$s</xliff:g> वापरत आहे."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ॲप्लिकेशन्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" आणि "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"कॅमेरा"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"मायक्रोफोन"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"सेन्सर बंद आहेत"</string>
<string name="device_services" msgid="1549944177856658705">"डिव्हाइस सेवा"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 37cbb7edf753..029571b656ea 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Tetapan"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Longgok Tmbunn SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> sedang menggunakan <xliff:g id="TYPES_LIST">%2$s</xliff:g> anda."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi sedang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> anda."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Penderia dimatikan"</string>
<string name="device_services" msgid="1549944177856658705">"Perkhidmatan Peranti"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 376ed2fd2d9a..6e632af3c5f4 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ဆက်တင်များ"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ရပါပြီ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> က သင်၏ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ကို အသုံးပြုနေသည်။"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"အပလီကေးရှင်းများက သင်၏ <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသည်။"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"၊ "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" နှင့် "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ကင်မရာ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"တည်နေရာ"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"မိုက်ခရိုဖုန်း"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"အာရုံခံကိရိယာများ ပိတ်ထားသည်"</string>
<string name="device_services" msgid="1549944177856658705">"စက်ပစ္စည်းဝန်ဆောင်မှုများ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ခေါင်းစဉ် မရှိပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 26268301333c..5e29ca48bf7b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Innstillinger"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Greit"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI-heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> bruker <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apper bruker <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"posisjon"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorer er av"</string>
<string name="device_services" msgid="1549944177856658705">"Enhetstjenester"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Ingen tittel"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index d962af76ec41..098e0b1911d1 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"सेटिङहरू"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"बुझेँ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ले तपाईंको <xliff:g id="TYPES_LIST">%2$s</xliff:g> प्रयोग गर्दै छ।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"एपहरूले तपाईंको <xliff:g id="TYPES_LIST">%s</xliff:g> प्रयोग गर्दै छन्‌।"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" र "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"क्यामेरा"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफोन"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"सेन्सरहरू निष्क्रिय छन्"</string>
<string name="device_services" msgid="1549944177856658705">"यन्त्रका सेवाहरू"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7a4de7516e05..e5012182eadc 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -433,7 +433,7 @@
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starten"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stoppen"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Apparaat"</string>
- <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Veeg omhoog om te schakelen tussen apps"</string>
+ <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swipe omhoog om te schakelen tussen apps"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Sleep naar rechts om snel tussen apps te schakelen"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Overzicht in-/uitschakelen"</string>
<string name="expanded_header_battery_charged" msgid="5307907517976548448">"Opgeladen"</string>
@@ -452,12 +452,12 @@
<string name="keyguard_more_overflow_text" msgid="5819512373606638727">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="7248696377626341060">"Minder urgente meldingen onderaan"</string>
<string name="notification_tap_again" msgid="4477318164947497249">"Tik nog eens om te openen"</string>
- <string name="keyguard_unlock" msgid="8031975796351361601">"Veeg omhoog om te openen"</string>
- <string name="keyguard_retry" msgid="886802522584053523">"Veeg omhoog om het opnieuw te proberen"</string>
+ <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
+ <string name="keyguard_retry" msgid="886802522584053523">"Swipe omhoog om het opnieuw te proberen"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <string name="phone_hint" msgid="6682125338461375925">"Vegen voor telefoon"</string>
- <string name="voice_hint" msgid="7476017460191291417">"Vegen vanaf pictogram voor spraakassistent"</string>
+ <string name="phone_hint" msgid="6682125338461375925">"Swipen voor telefoon"</string>
+ <string name="voice_hint" msgid="7476017460191291417">"Swipen vanaf icoon voor spraakassistent"</string>
<string name="camera_hint" msgid="4519495795000658637">"Vegen voor camera"</string>
<string name="interruption_level_none_with_warning" msgid="8394434073508145437">"Helemaal stil. Hiermee worden schermlezers ook op stil gezet."</string>
<string name="interruption_level_none" msgid="219484038314193379">"Helemaal stil"</string>
@@ -566,7 +566,7 @@
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"Vertrouwde gegevens openen"</string>
<string name="monitoring_description_network_logging" msgid="577305979174002252">"Je beheerder heeft netwerkregistratie ingeschakeld, waarmee verkeer op je apparaat wordt bijgehouden.\n\nNeem contact op met je beheerder voor meer informatie."</string>
- <string name="monitoring_description_vpn" msgid="1685428000684586870">"Je hebt een app toestemming gegeven voor het instellen van een VPN-verbinding.\n\nMet deze app kan je apparaat- en netwerkactiviteit worden gecontroleerd, inclusief e-mails, apps en websites."</string>
+ <string name="monitoring_description_vpn" msgid="1685428000684586870">"Je hebt een app rechten gegeven voor het instellen van een VPN-verbinding.\n\nMet deze app kan je apparaat- en netwerkactiviteit worden gecontroleerd, inclusief e-mails, apps en websites."</string>
<string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJe beheerder kan je netwerkactiviteit controleren, inclusief e-mails, apps en websites.\n\nNeem contact op met je beheerder voor meer informatie.\n\nJe bent ook verbonden met een VPN, waarmee je netwerkactiviteit kan worden gecontroleerd."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
<string name="monitoring_description_app" msgid="376868879287922929">"Je bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je netwerkactiviteit (waaronder e-mails, apps en websites) kan worden bijgehouden."</string>
@@ -644,7 +644,7 @@
<string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth en wifi"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Systeem-UI-tuner"</string>
<string name="show_battery_percentage" msgid="6235377891802910455">"Percentage ingebouwde batterij weergeven"</string>
- <string name="show_battery_percentage_summary" msgid="9053024758304102915">"Accupercentage weergeven in het pictogram op de statusbalk wanneer er niet wordt opgeladen"</string>
+ <string name="show_battery_percentage_summary" msgid="9053024758304102915">"Accupercentage weergeven in het icoon op de statusbalk wanneer er niet wordt opgeladen"</string>
<string name="quick_settings" msgid="6211774484997470203">"Snelle instellingen"</string>
<string name="status_bar" msgid="4357390266055077437">"Statusbalk"</string>
<string name="overview" msgid="3522318590458536816">"Overzicht"</string>
@@ -861,8 +861,8 @@
<string name="accessibility_key" msgid="3471162841552818281">"Aangepaste navigatieknop"</string>
<string name="left_keycode" msgid="8211040899126637342">"Toetscode links"</string>
<string name="right_keycode" msgid="2480715509844798438">"Toetscode rechts"</string>
- <string name="left_icon" msgid="5036278531966897006">"Pictogram links"</string>
- <string name="right_icon" msgid="1103955040645237425">"Pictogram rechts"</string>
+ <string name="left_icon" msgid="5036278531966897006">"Icoon links"</string>
+ <string name="right_icon" msgid="1103955040645237425">"Icoon rechts"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"Houd vast en sleep om tegels toe te voegen"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Houd vast en sleep om tegels opnieuw in te delen"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Sleep hier naartoe om te verwijderen"</string>
@@ -872,12 +872,12 @@
<string-array name="clock_options">
<item msgid="3986445361435142273">"Uren, minuten en seconden weergeven"</item>
<item msgid="1271006222031257266">"Uren en minuten weergeven (standaard)"</item>
- <item msgid="6135970080453877218">"Dit pictogram niet weergeven"</item>
+ <item msgid="6135970080453877218">"Dit icoon niet weergeven"</item>
</string-array>
<string-array name="battery_options">
<item msgid="7714004721411852551">"Percentage altijd weergeven"</item>
<item msgid="3805744470661798712">"Percentage weergeven tijdens opladen (standaard)"</item>
- <item msgid="8619482474544321778">"Dit pictogram niet weergeven"</item>
+ <item msgid="8619482474544321778">"Dit icoon niet weergeven"</item>
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Pictogrammen voor meldingen met lage prioriteit weergeven"</string>
<string name="other" msgid="429768510980739978">"Overig"</string>
@@ -970,7 +970,7 @@
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobiele data uitzetten?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"Je hebt dan geen toegang meer tot data of internet via <xliff:g id="CARRIER">%s</xliff:g>. Internet is alleen nog beschikbaar via wifi."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"je provider"</string>
- <string name="touch_filtered_warning" msgid="8119511393338714836">"Aangezien een app een toestemmingsverzoek afdekt, kan Instellingen je reactie niet verifiëren."</string>
+ <string name="touch_filtered_warning" msgid="8119511393338714836">"Aangezien een app een rechtenverzoek afdekt, kan Instellingen je reactie niet verifiëren."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g> toestaan om segmenten van <xliff:g id="APP_2">%2$s</xliff:g> weer te geven?"</string>
<string name="slice_permission_text_1" msgid="6675965177075443714">"- Deze kan informatie lezen van <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="slice_permission_text_2" msgid="6758906940360746983">"- Deze kan acties uitvoeren in <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Instellingen"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> gebruikt je <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps gebruiken je <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"locatie"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microfoon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensoren uit"</string>
<string name="device_services" msgid="1549944177856658705">"Apparaatservices"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Geen titel"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index e112f446acb1..bfd4bd77df31 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ସେଟିଂସ୍"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ବୁଝିଗଲି"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ହିପ୍ ଡମ୍ପ୍ କରନ୍ତୁ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ଆପ୍ଲିକେସନ୍‍ଗୁଡିକ ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ଏବଂ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"କ୍ୟାମେରା"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ଲୋକେସନ୍‍"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"ମାଇକ୍ରୋଫୋନ୍"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ସେନ୍ସର୍‍ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"</string>
<string name="device_services" msgid="1549944177856658705">"ଡିଭାଇସ୍‍ ସେବାଗୁଡିକ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"କୌଣସି ଶୀର୍ଷକ ନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6ac824b59e6b..1df919286a95 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ਸੈਟਿੰਗਾਂ"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ਸਮਝ ਲਿਆ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ਹੀਪ ਡੰਪ ਕਰੋ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ।"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ਅਤੇ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ਕੈਮਰਾ"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ਟਿਕਾਣਾ"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ਸੈਂਸਰ ਬੰਦ ਕਰੋ"</string>
<string name="device_services" msgid="1549944177856658705">"ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index f5ef1a045bdd..56fcbb20f5b5 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ustawienia"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Zrzut stosu SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> używa: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacje używają: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"aparat"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokalizacja"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Wyłącz czujniki"</string>
<string name="device_services" msgid="1549944177856658705">"Usługi urządzenia"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Bez tytułu"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index c8eaa0ddc4fb..88f603200dc5 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Configurações"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ok"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar heap SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string>
<string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 341efff0e4cd..5fdb2853551d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Definições"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar pilha SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"A app <xliff:g id="APP">%1$s</xliff:g> está a utilizar o(a) <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"As aplicações estão a utilizar o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"câmara"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string>
<string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
@@ -1015,7 +1022,7 @@
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"As conversas prioritárias irão:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecer na parte superior da secção de conversas."</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar a imagem do perfil no ecrã de bloqueio."</string>
- <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecem como balões flutuantes por cima de apps."</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecer como balões flutuantes por cima de apps."</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompem o modo Não incomodar."</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
<string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Definições"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c8eaa0ddc4fb..88f603200dc5 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Configurações"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ok"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar heap SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string>
<string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 08542c02c2e0..d5eecc76144c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -990,6 +990,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Setări"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Extrageți memoria SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> folosește <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicațiile folosesc <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" și "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"cameră foto"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"locație"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"microfon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzori dezactivați"</string>
<string name="device_services" msgid="1549944177856658705">"Servicii pentru dispozitiv"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 12c489e08e41..50850225c891 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Открыть настройки"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"ОК"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Передача SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"В приложении \"<xliff:g id="APP">%1$s</xliff:g>\" используется <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"В приложениях используется <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"местоположение"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчики отключены"</string>
<string name="device_services" msgid="1549944177856658705">"Сервисы устройства"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Без названия"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 412050f4bb7f..ff7e816f8336 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"සැකසීම්"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"තේරුණා"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ඔබේ <xliff:g id="TYPES_LIST">%2$s</xliff:g> භාවිත කරමින් සිටී."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"යෙදුම් ඔබේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරමින් සිටී."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" සහ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"කැමරාව"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ස්ථානය"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"මයික්‍රෝෆෝනය"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"සංවේදක ක්‍රියාවිරහිතයි"</string>
<string name="device_services" msgid="1549944177856658705">"උපාංග සේවා"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"මාතෘකාවක් නැත"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index f657d4fe71e7..a86da967ab62 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Nastavenia"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Dobre"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> používa zoznam <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofón"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Senzory sú vypnuté"</string>
<string name="device_services" msgid="1549944177856658705">"Služby zariadenia"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e1e5852098b9..b9039d8c3cb9 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Nastavitve"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"V redu"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izvoz kopice SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> uporablja <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije uporabljajo <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" in "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokacijo"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Izklop za tipala"</string>
<string name="device_services" msgid="1549944177856658705">"Storitve naprave"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Brez naslova"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 64d7a2ecac52..2972c5383bee 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Cilësimet"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"E kuptova"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Hidh grumbullin SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> po përdor <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacionet po përdorin <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dhe "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamerën"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"vendndodhjen"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonin"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorët joaktivë"</string>
<string name="device_services" msgid="1549944177856658705">"Shërbimet e pajisjes"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Pa titull"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index fd6f57e64113..77cbb96b3691 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -990,6 +990,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Подешавања"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Важи"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Издвоји SysUI мем."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Сензори су искључени"</string>
<string name="device_services" msgid="1549944177856658705">"Услуге за уређаје"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f96dd27aba6d..c7eda4567a68 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Inställningar"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI-heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="TYPES_LIST">%2$s</xliff:g> används av <xliff:g id="APP">%1$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> används av appar."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" och "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"plats"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorer har inaktiverats"</string>
<string name="device_services" msgid="1549944177856658705">"Enhetstjänster"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 8b8c24983e98..2804f2f1e106 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Mipangilio"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Nimeelewa"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> inatumia <xliff:g id="TYPES_LIST">%2$s</xliff:g> yako."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programu zinatumia <xliff:g id="TYPES_LIST">%s</xliff:g> yako."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" na "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"mahali"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"maikrofoni"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Umezima vitambuzi"</string>
<string name="device_services" msgid="1549944177856658705">"Huduma za Kifaa"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Wimbo hauna jina"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b97e266850c6..ee176fa3c57d 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"அமைப்புகள்"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"சரி"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"உங்கள் <xliff:g id="TYPES_LIST">%2$s</xliff:g>ஐ <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பயன்படுத்துகிறது."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றை ஆப்ஸ் பயன்படுத்துகின்றன."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" மற்றும் "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"கேமரா"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"இருப்பிடம்"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"மைக்ரோஃபோன்"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"சென்சார்களை ஆஃப் செய்தல்"</string>
<string name="device_services" msgid="1549944177856658705">"சாதன சேவைகள்"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"தலைப்பு இல்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 13319d9719b8..dc5ea1f29fb5 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"సెట్టింగ్‌లు"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"అర్థమైంది"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"డంప్ SysUI హీప్"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> మీ <xliff:g id="TYPES_LIST">%2$s</xliff:g>ని ఉపయోగిస్తోంది."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"అప్లికేషన్‌లు మీ <xliff:g id="TYPES_LIST">%s</xliff:g>ని ఉపయోగిస్తున్నాయి."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" మరియు "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"కెమెరా"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"లొకేషన్"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"మైక్రోఫోన్"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"సెన్సార్‌లు ఆఫ్"</string>
<string name="device_services" msgid="1549944177856658705">"పరికర సేవలు"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"శీర్షిక లేదు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index e1c0e7e7a614..ba9fd296f607 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"การตั้งค่า"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"รับทราบ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ใช้<xliff:g id="TYPES_LIST">%2$s</xliff:g>ของคุณอยู่"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"หลายแอปพลิเคชันใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณอยู่"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" และ "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"กล้องถ่ายรูป"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"ตำแหน่ง"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"ไมโครโฟน"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"ปิดเซ็นเซอร์"</string>
<string name="device_services" msgid="1549944177856658705">"บริการของอุปกรณ์"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"ไม่มีชื่อ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 20a34e1ded0d..069438f2caed 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Mga Setting"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Ginagamit ng <xliff:g id="APP">%1$s</xliff:g> ang iyong <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ginagamit ng mga application ang iyong <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" at "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"lokasyon"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikropono"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Naka-off ang mga sensor"</string>
<string name="device_services" msgid="1549944177856658705">"Mga Serbisyo ng Device"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Walang pamagat"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4146f307ac18..649b9af53ff6 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Ayarlar"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Anladım"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI Yığın Dökümü"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> şunları kullanıyor: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Uygulamalar şunları kullanıyor: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ve "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"konum"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensörler kapalı"</string>
<string name="device_services" msgid="1549944177856658705">"Cihaz Hizmetleri"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Başlıksız"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 11eb18cc48d2..6cb3ac8ce915 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -995,6 +995,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Налаштування"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"Додаток <xliff:g id="APP">%1$s</xliff:g> використовує <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Додатки використовують <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"місце"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"мікрофон"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Датчики вимкнено"</string>
<string name="device_services" msgid="1549944177856658705">"Сервіси на пристрої"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Без назви"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index d7645e9bcb5b..804c33436ea6 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"ترتیبات"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"سمجھ آ گئی"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> آپ کی <xliff:g id="TYPES_LIST">%2$s</xliff:g> کا استعمال کر رہی ہے۔"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ایپلیکیشنز آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں۔"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" اور "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"کیمرا"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"مقام"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"مائیکروفون"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"سینسرز آف ہیں"</string>
<string name="device_services" msgid="1549944177856658705">"آلہ کی سروس"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"کوئی عنوان نہیں ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 1fc4f9bea270..6193d33961e6 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Sozlamalar"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> ishlatmoqda: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ilovalarda ishlatilmoqda: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" va "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"joylashuv"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensorlar nofaol"</string>
<string name="device_services" msgid="1549944177856658705">"Qurilma xizmatlari"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Nomsiz"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 8df5ee530210..97ffbc623e02 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Cài đặt"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Trích xuất bộ nhớ SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> đang dùng <xliff:g id="TYPES_LIST">%2$s</xliff:g> của bạn."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Các ứng dụng đang dùng <xliff:g id="TYPES_LIST">%s</xliff:g> của bạn."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" và "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"máy ảnh"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"vị trí"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"micrô"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Tắt cảm biến"</string>
<string name="device_services" msgid="1549944177856658705">"Dịch vụ cho thiết bị"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Không có tiêu đề"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c51982cddac3..b9b146c9fb4b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"设置"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"知道了"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"转储 SysUI 堆"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g>正在使用您的<xliff:g id="TYPES_LIST">%2$s</xliff:g>。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多个应用正在使用您的<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"相机"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"位置信息"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"麦克风"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"已关闭传感器"</string>
<string name="device_services" msgid="1549944177856658705">"设备服务"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"无标题"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index aa9945fbd956..f2cb185078b5 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"設定"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"知道了"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"轉儲 SysUI 堆"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"「<xliff:g id="APP">%1$s</xliff:g>」正在使用<xliff:g id="TYPES_LIST">%2$s</xliff:g>。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"感應器已關閉"</string>
<string name="device_services" msgid="1549944177856658705">"裝置服務"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 92bdfc3f1219..69b52946d698 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"設定"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"我知道了"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"傾印 SysUI 記憶體快照"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"「<xliff:g id="APP">%1$s</xliff:g>」正在使用<xliff:g id="TYPES_LIST">%2$s</xliff:g>。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"已關閉感應器"</string>
<string name="device_services" msgid="1549944177856658705">"裝置服務"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 4ae126799141..5b899f93e5f9 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -985,6 +985,13 @@
<string name="open_saver_setting_action" msgid="2111461909782935190">"Izilungiselelo"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Ngiyezwa"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"I-Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"I-<xliff:g id="APP">%1$s</xliff:g> isebenzisa i-<xliff:g id="TYPES_LIST">%2$s</xliff:g> yakho."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Izinhlelo zokusebenza zisebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho."</string>
+ <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
+ <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" kanye "</string>
+ <string name="privacy_type_camera" msgid="7974051382167078332">"ikhamera"</string>
+ <string name="privacy_type_location" msgid="7991481648444066703">"indawo"</string>
+ <string name="privacy_type_microphone" msgid="9136763906797732428">"imakrofoni"</string>
<string name="sensor_privacy_mode" msgid="4462866919026513692">"Izinzwa zivaliwe"</string>
<string name="device_services" msgid="1549944177856658705">"Amasevisi edivayisi"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Asikho isihloko"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index f407a8dcc57f..fa620df12b87 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -161,10 +161,6 @@
<!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
<integer name="ambient_notification_extension_time">10000</integer>
- <!-- In multi-window, determines whether the stack where recents lives should grow from
- the smallest position when being launched. -->
- <bool name="recents_grow_in_multiwindow">true</bool>
-
<!-- Animation duration when using long press on recents to dock -->
<integer name="long_press_dock_anim_duration">250</integer>
@@ -522,6 +518,8 @@
<!-- Defines the blacklist for system icons. That is to say, the icons in the status bar that
are part of the blacklist are never displayed. Each item in the blacklist must be a string
defined in core/res/res/config.xml to properly blacklist the icon.
+
+ TODO: See if we can rename this config variable.
-->
<string-array name="config_statusBarIconBlackList" translatable="false">
<item>@*android:string/status_bar_rotate</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8b6543ac73bd..77d3f4513957 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2838,4 +2838,9 @@
<string name="udfps_hbm_enable_command" translatable="false"></string>
<!-- Device-specific payload for disabling the high-brightness mode -->
<string name="udfps_hbm_disable_command" translatable="false"></string>
+
+ <!-- One-Handed Tutorial title [CHAR LIMIT=60] -->
+ <string name="one_handed_tutorial_title">Using one-handed mode</string>
+ <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] -->
+ <string name="one_handed_tutorial_description">To exit, swipe up from the bottom of the screen or tap anywhere above the app</string>
</resources>
diff --git a/packages/SystemUI/res/xml/one_handed_tutorial.xml b/packages/SystemUI/res/xml/one_handed_tutorial.xml
new file mode 100644
index 000000000000..dc54caf0f14a
--- /dev/null
+++ b/packages/SystemUI/res/xml/one_handed_tutorial.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ 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
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/one_handed_tutorial_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal | center_vertical"
+ android:background="@android:color/transparent">
+
+ <ImageView
+ android:id="@+id/one_handed_tutorial_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="6dp"
+ android:layout_marginBottom="0dp"
+ android:gravity="center_horizontal"
+ android:src="@drawable/one_handed_tutorial"
+ android:scaleType="centerInside" />
+
+ <TextView
+ android:id="@+id/one_handed_tutorial_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="6dp"
+ android:layout_marginBottom="0dp"
+ android:gravity="center_horizontal"
+ android:textAlignment="center"
+ android:fontFamily="google-sans-medium"
+ android:text="@string/one_handed_tutorial_title"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:textColor="@android:color/white"/>
+
+ <TextView
+ android:id="@+id/one_handed_tutorial_description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="6dp"
+ android:layout_marginBottom="0dp"
+ android:layout_marginStart="86dp"
+ android:layout_marginEnd="86dp"
+ android:gravity="center_horizontal"
+ android:fontFamily="roboto-regular"
+ android:text="@string/one_handed_tutorial_description"
+ android:textAlignment="center"
+ android:textSize="14sp"
+ android:textStyle="normal"
+ android:alpha="0.7"
+ android:textColor="@android:color/white"/>
+</LinearLayout>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 158763a9ddab..ecf1c2c91770 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -1,10 +1,7 @@
package com.android.keyguard;
-import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
-
import android.animation.Animator;
import android.animation.ValueAnimator;
-import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.Style;
@@ -24,16 +21,10 @@ import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextClock;
-import androidx.annotation.VisibleForTesting;
-
import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
-import com.android.keyguard.clock.ClockManager;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.ClockPlugin;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
@@ -42,16 +33,12 @@ import java.io.PrintWriter;
import java.util.Arrays;
import java.util.TimeZone;
-import javax.inject.Inject;
-import javax.inject.Named;
-
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch";
- private static final boolean CUSTOM_CLOCKS_ENABLED = true;
/**
* Animation fraction when text is transitioned to/from bold.
@@ -59,21 +46,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
private static final float TO_BOLD_TRANSITION_FRACTION = 0.7f;
/**
- * Controller used to track StatusBar state to know when to show the big_clock_container.
- */
- private final StatusBarStateController mStatusBarStateController;
-
- /**
- * Color extractor used to apply colors from wallpaper to custom clock faces.
- */
- private final SysuiColorExtractor mSysuiColorExtractor;
-
- /**
- * Manager used to know when to show a custom clock face.
- */
- private final ClockManager mClockManager;
-
- /**
* Layout transition that scales the default clock face.
*/
private final Transition mTransition;
@@ -130,42 +102,8 @@ public class KeyguardClockSwitch extends RelativeLayout {
private boolean mSupportsDarkText;
private int[] mColorPalette;
- /**
- * Track the state of the status bar to know when to hide the big_clock_container.
- */
- private int mStatusBarState;
-
- private final StatusBarStateController.StateListener mStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onStateChanged(int newState) {
- mStatusBarState = newState;
- updateBigClockVisibility();
- }
- };
-
- private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
-
- /**
- * Listener for changes to the color palette.
- *
- * The color palette changes when the wallpaper is changed.
- */
- private final OnColorsChangedListener mColorsListener = (extractor, which) -> {
- if ((which & WallpaperManager.FLAG_LOCK) != 0) {
- updateColors();
- }
- };
-
- @Inject
- public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
- StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor,
- ClockManager clockManager) {
+ public KeyguardClockSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
- mStatusBarStateController = statusBarStateController;
- mStatusBarState = mStatusBarStateController.getState();
- mSysuiColorExtractor = colorExtractor;
- mClockManager = clockManager;
mClockTransition = new ClockVisibilityTransition().setCutoff(
1 - TO_BOLD_TRANSITION_FRACTION);
@@ -197,29 +135,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
}
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (CUSTOM_CLOCKS_ENABLED) {
- mClockManager.addOnClockChangedListener(mClockChangedListener);
- }
- mStatusBarStateController.addCallback(mStateListener);
- mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener);
- updateColors();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (CUSTOM_CLOCKS_ENABLED) {
- mClockManager.removeOnClockChangedListener(mClockChangedListener);
- }
- mStatusBarStateController.removeCallback(mStateListener);
- mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener);
- setClockPlugin(null);
- }
-
- private void setClockPlugin(ClockPlugin plugin) {
+ void setClockPlugin(ClockPlugin plugin, int statusBarState) {
// Disconnect from existing plugin.
if (mClockPlugin != null) {
View smallClockView = mClockPlugin.getView();
@@ -228,7 +144,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
if (mBigClockContainer != null) {
mBigClockContainer.removeAllViews();
- updateBigClockVisibility();
+ updateBigClockVisibility(statusBarState);
}
mClockPlugin.onDestroyView();
mClockPlugin = null;
@@ -256,7 +172,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
View bigClockView = plugin.getBigClockView();
if (bigClockView != null && mBigClockContainer != null) {
mBigClockContainer.addView(bigClockView);
- updateBigClockVisibility();
+ updateBigClockVisibility(statusBarState);
}
// Hide default clock.
if (!plugin.shouldShowStatusArea()) {
@@ -275,7 +191,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
/**
* Set container for big clock face appearing behind NSSL and KeyguardStatusView.
*/
- public void setBigClockContainer(ViewGroup container) {
+ public void setBigClockContainer(ViewGroup container, int statusBarState) {
if (mClockPlugin != null && container != null) {
View bigClockView = mClockPlugin.getBigClockView();
if (bigClockView != null) {
@@ -283,7 +199,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
mBigClockContainer = container;
- updateBigClockVisibility();
+ updateBigClockVisibility(statusBarState);
}
/**
@@ -407,9 +323,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
- private void updateColors() {
- ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
- WallpaperManager.FLAG_LOCK);
+ void updateColors(ColorExtractor.GradientColors colors) {
mSupportsDarkText = colors.supportsDarkText();
mColorPalette = colors.getColorPalette();
if (mClockPlugin != null) {
@@ -417,12 +331,12 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
- private void updateBigClockVisibility() {
+ void updateBigClockVisibility(int statusBarState) {
if (mBigClockContainer == null) {
return;
}
- final boolean inDisplayState = mStatusBarState == StatusBarState.KEYGUARD
- || mStatusBarState == StatusBarState.SHADE_LOCKED;
+ final boolean inDisplayState = statusBarState == StatusBarState.KEYGUARD
+ || statusBarState == StatusBarState.SHADE_LOCKED;
final int visibility = !mShowingHeader && inDisplayState
&& mBigClockContainer.getChildCount() != 0 ? View.VISIBLE : View.GONE;
if (mBigClockContainer.getVisibility() != visibility) {
@@ -506,16 +420,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
- @VisibleForTesting(otherwise = VisibleForTesting.NONE)
- ClockManager.ClockChangedListener getClockChangedListener() {
- return mClockChangedListener;
- }
-
- @VisibleForTesting(otherwise = VisibleForTesting.NONE)
- StatusBarStateController.StateListener getStateListener() {
- return mStateListener;
- }
-
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardClockSwitch:");
pw.println(" mClockPlugin: " + mClockPlugin);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
new file mode 100644
index 000000000000..f17f1ca797e0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -0,0 +1,119 @@
+/*
+ * 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.keyguard;
+
+import android.app.WallpaperManager;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+
+import javax.inject.Inject;
+
+/**
+ * Injectable controller for {@link KeyguardClockSwitch}.
+ */
+public class KeyguardClockSwitchController {
+ private static final boolean CUSTOM_CLOCKS_ENABLED = true;
+
+ private final StatusBarStateController mStatusBarStateController;
+ private final SysuiColorExtractor mColorExtractor;
+ private final ClockManager mClockManager;
+ private KeyguardClockSwitch mView;
+
+ private final StatusBarStateController.StateListener mStateListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onStateChanged(int newState) {
+ mView.updateBigClockVisibility(newState);
+ }
+ };
+
+ /**
+ * Listener for changes to the color palette.
+ *
+ * The color palette changes when the wallpaper is changed.
+ */
+ private final ColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> {
+ if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+ mView.updateColors(getGradientColors());
+ }
+ };
+
+ private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
+
+ private final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ if (CUSTOM_CLOCKS_ENABLED) {
+ mClockManager.addOnClockChangedListener(mClockChangedListener);
+ }
+ mStatusBarStateController.addCallback(mStateListener);
+ mColorExtractor.addOnColorsChangedListener(mColorsListener);
+ mView.updateColors(getGradientColors());
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (CUSTOM_CLOCKS_ENABLED) {
+ mClockManager.removeOnClockChangedListener(mClockChangedListener);
+ }
+ mStatusBarStateController.removeCallback(mStateListener);
+ mColorExtractor.removeOnColorsChangedListener(mColorsListener);
+ mView.setClockPlugin(null, mStatusBarStateController.getState());
+ }
+ };
+
+ @Inject
+ public KeyguardClockSwitchController(StatusBarStateController statusBarStateController,
+ SysuiColorExtractor colorExtractor, ClockManager clockManager) {
+ mStatusBarStateController = statusBarStateController;
+ mColorExtractor = colorExtractor;
+ mClockManager = clockManager;
+ }
+
+ /**
+ * Attach the controller to the view it relates to.
+ */
+ public void attach(KeyguardClockSwitch view) {
+ mView = view;
+ if (mView.isAttachedToWindow()) {
+ mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
+ }
+ mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+ }
+
+ /**
+ * Set container for big clock face appearing behind NSSL and KeyguardStatusView.
+ */
+ public void setBigClockContainer(ViewGroup bigClockContainer) {
+ mView.setBigClockContainer(bigClockContainer, mStatusBarStateController.getState());
+ }
+
+ private void setClockPlugin(ClockPlugin plugin) {
+ mView.setClockPlugin(plugin, mStatusBarStateController.getState());
+ }
+
+ private ColorExtractor.GradientColors getGradientColors() {
+ return mColorExtractor.getColors(WallpaperManager.FLAG_LOCK);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 58698151b655..521bb8d58c2b 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -225,7 +225,7 @@ public class BatteryMeterView extends LinearLayout implements
}
Dependency.get(TunerService.class)
- .addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ .addTunable(this, StatusBarIconController.ICON_HIDE_LIST);
mIsSubscribedForTunerUpdates = true;
}
@@ -278,8 +278,8 @@ public class BatteryMeterView extends LinearLayout implements
@Override
public void onTuningChanged(String key, String newValue) {
- if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
- ArraySet<String> icons = StatusBarIconController.getIconBlacklist(
+ if (StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
+ ArraySet<String> icons = StatusBarIconController.getIconHideList(
getContext(), newValue);
setVisibility(icons.contains(mSlotBattery) ? View.GONE : View.VISIBLE);
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/DisplayIdIndexSupplier.java b/packages/SystemUI/src/com/android/systemui/accessibility/DisplayIdIndexSupplier.java
index 769a344eedac..d5aac1a95847 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/DisplayIdIndexSupplier.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/DisplayIdIndexSupplier.java
@@ -60,6 +60,20 @@ abstract class DisplayIdIndexSupplier<T> {
return instance;
}
+ /**
+ * Gets the object by the element index.
+ *
+ * <p> If the index is bigger than the array size, an {@link ArrayIndexOutOfBoundsException} is
+ * thrown for apps targeting {@link android.os.Build.VERSION_CODES#Q} and later </p>
+ *
+ * @param index the element index
+ * @return T
+ * @see SparseArray#valueAt(int)
+ */
+ public T valueAt(int index) {
+ return mSparseArray.valueAt(index);
+ }
+
@NonNull
protected abstract T createInstance(Display display);
@@ -78,4 +92,13 @@ abstract class DisplayIdIndexSupplier<T> {
public void clear() {
mSparseArray.clear();
}
+
+ /**
+ * Gets the element size.
+ *
+ * @return size of all elements
+ */
+ public int getSize() {
+ return mSparseArray.size();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index 68a0a65ef50f..34f721c94ed2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -18,6 +18,7 @@ package com.android.systemui.accessibility;
import android.annotation.NonNull;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.provider.Settings;
import android.view.Gravity;
@@ -102,6 +103,14 @@ class MagnificationModeSwitch {
.start();
}
+ void onConfigurationChanged(int configDiff) {
+ if ((configDiff & ActivityInfo.CONFIG_DENSITY) == 0) {
+ return;
+ }
+ applyResourcesValues();
+ mImageView.setImageResource(getIconResId(mMagnificationMode));
+ }
+
private void toggleMagnificationMode() {
final int newMode =
mMagnificationMode ^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
@@ -112,7 +121,7 @@ class MagnificationModeSwitch {
}
private static ImageView createView(Context context) {
- ImageView imageView = new ImageView(context);
+ ImageView imageView = new ImageView(context);
imageView.setClickable(true);
imageView.setFocusable(true);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java b/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java
index ffc70bcf63d0..fe07ab67c707 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java
@@ -36,7 +36,7 @@ import javax.inject.Singleton;
@Singleton
public class ModeSwitchesController {
- private final SwitchSupplier mSwitchSupplier;
+ private final DisplayIdIndexSupplier<MagnificationModeSwitch> mSwitchSupplier;
public ModeSwitchesController(Context context) {
mSwitchSupplier = new SwitchSupplier(context,
@@ -44,7 +44,7 @@ public class ModeSwitchesController {
}
@VisibleForTesting
- ModeSwitchesController(SwitchSupplier switchSupplier) {
+ ModeSwitchesController(DisplayIdIndexSupplier<MagnificationModeSwitch> switchSupplier) {
mSwitchSupplier = switchSupplier;
}
@@ -81,8 +81,22 @@ public class ModeSwitchesController {
magnificationModeSwitch.removeButton();
}
- @VisibleForTesting
- static class SwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
+ /**
+ * Called when the configuration has changed, and it updates magnification button UI.
+ *
+ * @param configDiff a bit mask of the differences between the configurations
+ */
+ @MainThread
+ void onConfigurationChanged(int configDiff) {
+ for (int i = 0; i < mSwitchSupplier.getSize(); i++) {
+ final MagnificationModeSwitch magnificationModeSwitch = mSwitchSupplier.valueAt(i);
+ if (magnificationModeSwitch != null) {
+ magnificationModeSwitch.onConfigurationChanged(configDiff);
+ }
+ }
+ }
+
+ private static class SwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
private final Context mContext;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 78af8aa19b44..816bcf8f274b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -84,6 +84,9 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
if (mWindowMagnificationController != null) {
mWindowMagnificationController.onConfigurationChanged(configDiff);
}
+ if (mModeSwitchesController != null) {
+ mModeSwitchesController.onConfigurationChanged(configDiff);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 87489262a420..27863ba6c857 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -697,6 +697,9 @@ class Bubble implements BubbleViewProvider {
pw.print(" desiredHeight: "); pw.println(getDesiredHeightString());
pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification());
pw.print(" autoExpand: "); pw.println(shouldAutoExpand());
+ if (mExpandedView != null) {
+ mExpandedView.dump(fd, pw, args);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 434bf49ac878..bb572191fe3c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -25,6 +25,8 @@ import static android.service.notification.NotificationListenerService.REASON_CA
import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_CLICK;
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
+import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.View.INVISIBLE;
@@ -100,8 +102,11 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.coordinator.BubbleCoordinator;
+import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -277,7 +282,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
* This can happen when an app cancels a bubbled notification or when the user dismisses a
* bubble.
*/
- void removeNotification(@NonNull NotificationEntry entry, int reason);
+ void removeNotification(
+ @NonNull NotificationEntry entry,
+ @NonNull DismissedByUserStats stats,
+ int reason);
/**
* Called when a bubbled notification has changed whether it should be
@@ -543,6 +551,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
}
});
+ // The new pipeline takes care of this as a NotifDismissInterceptor BubbleCoordinator
mNotificationEntryManager.addNotificationRemoveInterceptor(
new NotificationRemoveInterceptor() {
@Override
@@ -551,7 +560,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
NotificationEntry entry,
int dismissReason) {
final boolean isClearAll = dismissReason == REASON_CANCEL_ALL;
- final boolean isUserDimiss = dismissReason == REASON_CANCEL
+ final boolean isUserDismiss = dismissReason == REASON_CANCEL
|| dismissReason == REASON_CLICK;
final boolean isAppCancel = dismissReason == REASON_APP_CANCEL
|| dismissReason == REASON_APP_CANCEL_ALL;
@@ -562,7 +571,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
// previously been dismissed & entry.isRowDismissed would still be true
boolean userRemovedNotif =
(entry != null && entry.isRowDismissed() && !isAppCancel)
- || isClearAll || isUserDimiss || isSummaryCancel;
+ || isClearAll || isUserDismiss || isSummaryCancel;
if (userRemovedNotif) {
return handleDismissalInterception(entry);
@@ -591,8 +600,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
addNotifCallback(new NotifCallback() {
@Override
- public void removeNotification(NotificationEntry entry, int reason) {
- mNotificationEntryManager.performRemoveNotification(entry.getSbn(), reason);
+ public void removeNotification(
+ NotificationEntry entry,
+ DismissedByUserStats dismissedByUserStats,
+ int reason
+ ) {
+ mNotificationEntryManager.performRemoveNotification(entry.getSbn(),
+ dismissedByUserStats, reason);
}
@Override
@@ -612,7 +626,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
mNotificationEntryManager.getActiveNotificationUnfiltered(
mBubbleData.getSummaryKey(groupKey));
if (summary != null) {
- mNotificationEntryManager.performRemoveNotification(summary.getSbn(),
+ mNotificationEntryManager.performRemoveNotification(
+ summary.getSbn(),
+ getDismissedByUserStats(summary, false),
UNDEFINED_DISMISS_REASON);
}
}
@@ -634,7 +650,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
boolean isSummaryThisNotif = summary.getKey().equals(entry.getKey());
if (!isSummaryThisNotif && (summaryChildren == null
|| summaryChildren.isEmpty())) {
- mNotificationEntryManager.performRemoveNotification(summary.getSbn(),
+ mNotificationEntryManager.performRemoveNotification(
+ summary.getSbn(),
+ getDismissedByUserStats(summary, false),
UNDEFINED_DISMISS_REASON);
}
}
@@ -1331,7 +1349,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
// time to actually remove it
for (NotifCallback cb : mCallbacks) {
if (entry != null) {
- cb.removeNotification(entry, REASON_CANCEL);
+ cb.removeNotification(
+ entry,
+ getDismissedByUserStats(entry, true),
+ REASON_CANCEL);
}
}
} else {
@@ -1487,7 +1508,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
} else {
// non-bubbled children can be removed
for (NotifCallback cb : mCallbacks) {
- cb.removeNotification(child, REASON_GROUP_SUMMARY_CANCELED);
+ cb.removeNotification(
+ child,
+ getDismissedByUserStats(child, true),
+ REASON_GROUP_SUMMARY_CANCELED);
}
}
}
@@ -1502,6 +1526,25 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
}
/**
+ * Gets the DismissedByUserStats used by {@link NotificationEntryManager}.
+ * Will not be necessary when using the new notification pipeline's {@link NotifCollection}.
+ * Instead, this is taken care of by {@link BubbleCoordinator}.
+ */
+ private DismissedByUserStats getDismissedByUserStats(
+ NotificationEntry entry,
+ boolean isVisible) {
+ return new DismissedByUserStats(
+ DISMISSAL_BUBBLE,
+ DISMISS_SENTIMENT_NEUTRAL,
+ NotificationVisibility.obtain(
+ entry.getKey(),
+ entry.getRanking().getRank(),
+ mNotificationEntryManager.getActiveNotificationsCount(),
+ isVisible,
+ NotificationLogger.getNotificationLocation(entry)));
+ }
+
+ /**
* Updates the visibility of the bubbles based on current state.
* Does not un-bubble, just hides or un-hides.
* Updates stack description for TalkBack focus.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index e26aa554dd61..d0f61817d1cc 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -34,6 +34,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPAND
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -77,6 +78,9 @@ import com.android.systemui.R;
import com.android.systemui.recents.TriangleShape;
import com.android.systemui.statusbar.AlphaOptimizedButton;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* Container for the expanded bubble view, handles rendering the caret and settings icon.
*/
@@ -458,15 +462,6 @@ public class BubbleExpandedView extends LinearLayout {
mPointerView.setBackground(mPointerDrawable);
}
- /**
- * Hides the IME if it's showing. This is currently done by dispatching a back press to the AV.
- */
- void hideImeIfVisible() {
- if (mKeyboardVisible) {
- performBackPressIfNeeded();
- }
- }
-
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
@@ -602,14 +597,17 @@ public class BubbleExpandedView extends LinearLayout {
*/
void update(Bubble bubble) {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
- Log.d(TAG, "update: bubble=" + (bubble != null ? bubble.getKey() : "null"));
+ Log.d(TAG, "update: bubble=" + bubble);
+ }
+ if (mStackView == null) {
+ Log.w(TAG, "Stack is null for bubble: " + bubble);
+ return;
}
boolean isNew = mBubble == null || didBackingContentChange(bubble);
if (isNew || bubble != null && bubble.getKey().equals(mBubble.getKey())) {
mBubble = bubble;
mSettingsIcon.setContentDescription(getResources().getString(
R.string.bubbles_settings_button_description, bubble.getAppName()));
-
mSettingsIcon.setAccessibilityDelegate(
new AccessibilityDelegate() {
@Override
@@ -817,4 +815,15 @@ public class BubbleExpandedView extends LinearLayout {
}
return null;
}
+
+ /**
+ * Description of current expanded view state.
+ */
+ public void dump(
+ @NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.print("BubbleExpandedView");
+ pw.print(" taskId: "); pw.println(mTaskId);
+ pw.print(" activityViewStatus: "); pw.println(mActivityViewStatus);
+ pw.print(" stackView: "); pw.println(mStackView);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index ea12c9598b91..b3fbfd6a0f30 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -1081,11 +1081,10 @@ public class BubbleStackView extends FrameLayout
final Bubble bubble = mBubbleData.getSelectedBubble();
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
final Intent intent = bubble.getSettingsIntent(mContext);
- collapseStack(() -> {
- mContext.startActivityAsUser(intent, bubble.getUser());
- logBubbleEvent(bubble,
- SysUiStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
- });
+ mBubbleData.setExpanded(false);
+ mContext.startActivityAsUser(intent, bubble.getUser());
+ logBubbleEvent(bubble,
+ SysUiStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
}
});
@@ -1769,36 +1768,6 @@ public class BubbleStackView extends FrameLayout
}
}
- /**
- * Dismiss the stack of bubbles.
- *
- * @deprecated
- */
- @Deprecated
- void stackDismissed(int reason) {
- if (DEBUG_BUBBLE_STACK_VIEW) {
- Log.d(TAG, "stackDismissed: reason=" + reason);
- }
- mBubbleData.dismissAll(reason);
- logBubbleEvent(null /* no bubble associated with bubble stack dismiss */,
- SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_DISMISSED);
- }
-
- /**
- * @deprecated use {@link #setExpanded(boolean)} and
- * {@link BubbleData#setSelectedBubble(Bubble)}
- */
- @Deprecated
- @MainThread
- void collapseStack(Runnable endRunnable) {
- if (DEBUG_BUBBLE_STACK_VIEW) {
- Log.d(TAG, "collapseStack(endRunnable)");
- }
- mBubbleData.setExpanded(false);
- // TODO - use the runnable at end of animation
- endRunnable.run();
- }
-
void showExpandedViewContents(int displayId) {
if (mExpandedBubble != null
&& mExpandedBubble.getExpandedView() != null
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
index 1929fc4e9dbf..5749169b881a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
@@ -103,11 +103,12 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
@Override
protected void onPostExecute(BubbleViewInfo viewInfo) {
- if (viewInfo != null) {
- mBubble.setViewInfo(viewInfo);
- if (mCallback != null && !isCancelled()) {
- mCallback.onBubbleViewsReady(mBubble);
- }
+ if (isCancelled() || viewInfo == null) {
+ return;
+ }
+ mBubble.setViewInfo(viewInfo);
+ if (mCallback != null) {
+ mCallback.onBubbleViewsReady(mBubble);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
index 900c11f0830e..9fdbb6daca51 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
@@ -29,7 +29,6 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.onehanded.dagger.OneHandedModule;
-import com.android.systemui.pip.phone.PipMenuActivity;
import com.android.systemui.pip.phone.dagger.PipModule;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
@@ -133,9 +132,4 @@ public interface SystemUIRootComponent {
* Member injection into the supplied argument.
*/
void inject(KeyguardSliceProvider keyguardSliceProvider);
-
- /**
- * Member injection into the supplied argument.
- */
- void inject(PipMenuActivity pipMenuActivity);
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 075318b3f1f7..de5316885b94 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -135,6 +135,7 @@ class MediaCarouselController @Inject constructor(
}
override fun onOverlayChanged() {
+ recreatePlayers()
inflateSettingsButton()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index c2631c923e45..1ae54d60d3fa 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -55,16 +55,16 @@ class SeekBarObserver(private val holder: PlayerViewHolder) : Observer<SeekBarVi
holder.seekBar.maxHeight = seekBarDefaultMaxHeight
}
- data.elapsedTime?.let {
- holder.seekBar.setProgress(it)
- holder.elapsedTimeView.setText(DateUtils.formatElapsedTime(
- it / DateUtils.SECOND_IN_MILLIS))
- }
-
data.duration?.let {
holder.seekBar.setMax(it)
holder.totalTimeView.setText(DateUtils.formatElapsedTime(
it / DateUtils.SECOND_IN_MILLIS))
}
+
+ data.elapsedTime?.let {
+ holder.seekBar.setProgress(it)
+ holder.elapsedTimeView.setText(DateUtils.formatElapsedTime(
+ it / DateUtils.SECOND_IN_MILLIS))
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java
index c581ac677532..264ace749383 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java
@@ -42,4 +42,10 @@ public interface OneHandedAnimationCallback {
default void onOneHandedAnimationCancel(
OneHandedAnimationController.OneHandedTransitionAnimator animator) {
}
+
+ /**
+ * Called when OneHanded animator is updating offset
+ */
+ default void onTutorialAnimationUpdate(int offset) {}
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java
index 1926c44abcba..2b07ac3f4d8a 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java
@@ -28,7 +28,9 @@ import androidx.annotation.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import javax.inject.Inject;
@@ -121,7 +123,8 @@ public class OneHandedAnimationController {
private T mEndValue;
private T mCurrentValue;
- private OneHandedAnimationCallback mOneHandedAnimationCallback;
+ private final List<OneHandedAnimationCallback> mOneHandedAnimationCallbacks =
+ new ArrayList<>();
private OneHandedSurfaceTransactionHelper mSurfaceTransactionHelper;
private OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
@@ -142,9 +145,11 @@ public class OneHandedAnimationController {
@Override
public void onAnimationStart(Animator animation) {
mCurrentValue = mStartValue;
- if (mOneHandedAnimationCallback != null) {
- mOneHandedAnimationCallback.onOneHandedAnimationStart(this);
- }
+ mOneHandedAnimationCallbacks.forEach(
+ (callback) -> {
+ callback.onOneHandedAnimationStart(this);
+ }
+ );
}
@Override
@@ -152,17 +157,21 @@ public class OneHandedAnimationController {
mCurrentValue = mEndValue;
final SurfaceControl.Transaction tx = newSurfaceControlTransaction();
onEndTransaction(mLeash, tx);
- if (mOneHandedAnimationCallback != null) {
- mOneHandedAnimationCallback.onOneHandedAnimationEnd(tx, this);
- }
+ mOneHandedAnimationCallbacks.forEach(
+ (callback) -> {
+ callback.onOneHandedAnimationEnd(tx, this);
+ }
+ );
}
@Override
public void onAnimationCancel(Animator animation) {
mCurrentValue = mEndValue;
- if (mOneHandedAnimationCallback != null) {
- mOneHandedAnimationCallback.onOneHandedAnimationCancel(this);
- }
+ mOneHandedAnimationCallbacks.forEach(
+ (callback) -> {
+ callback.onOneHandedAnimationCancel(this);
+ }
+ );
}
@Override
@@ -173,6 +182,11 @@ public class OneHandedAnimationController {
public void onAnimationUpdate(ValueAnimator animation) {
applySurfaceControlTransaction(mLeash, newSurfaceControlTransaction(),
animation.getAnimatedFraction());
+ mOneHandedAnimationCallbacks.forEach(
+ (callback) -> {
+ callback.onTutorialAnimationUpdate(((Rect) mCurrentValue).top);
+ }
+ );
}
void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
@@ -192,9 +206,9 @@ public class OneHandedAnimationController {
mSurfaceTransactionHelper = helper;
}
- OneHandedTransitionAnimator<T> setOneHandedAnimationCallback(
+ OneHandedTransitionAnimator<T> setOneHandedAnimationCallbacks(
OneHandedAnimationCallback callback) {
- mOneHandedAnimationCallback = callback;
+ mOneHandedAnimationCallbacks.add(callback);
return this;
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
index c0b9258f39fd..8550959aa2c4 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -82,6 +82,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implemen
private OneHandedAnimationController mAnimationController;
private OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
+ private OneHandedTutorialHandler mTutorialHandler;
private List<OneHandedTransitionCallback> mTransitionCallbacks = new ArrayList<>();
@VisibleForTesting
@@ -148,7 +149,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implemen
@Inject
public OneHandedDisplayAreaOrganizer(Context context,
DisplayController displayController,
- OneHandedAnimationController animationController) {
+ OneHandedAnimationController animationController,
+ OneHandedTutorialHandler tutorialHandler) {
mUpdateHandler = new Handler(OneHandedThread.get().getLooper(), mUpdateCallback);
mAnimationController = animationController;
mDisplayController = displayController;
@@ -157,6 +159,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implemen
mEnterExitAnimationDurationMs = context.getResources().getInteger(
com.android.systemui.R.integer.config_one_handed_translate_animation_duration);
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
+ mTutorialHandler = tutorialHandler;
}
@Override
@@ -272,7 +275,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implemen
mAnimationController.getAnimator(leash, fromBounds, toBounds);
if (animator != null) {
animator.setTransitionDirection(direction)
- .setOneHandedAnimationCallback(mOneHandedAnimationCallback)
+ .setOneHandedAnimationCallbacks(mOneHandedAnimationCallback)
+ .setOneHandedAnimationCallbacks(mTutorialHandler.getAnimationCallback())
.setDuration(durationMs)
.start();
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
index 71c5f8020330..ded386159dca 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
@@ -53,8 +53,8 @@ import javax.inject.Singleton;
*/
@Singleton
public class OneHandedGestureHandler implements OneHandedTransitionCallback,
- NavigationModeController.ModeChangedListener,
- DisplayChangeController.OnDisplayChangingListener {
+ NavigationModeController.ModeChangedListener,
+ DisplayChangeController.OnDisplayChangingListener {
private static final String TAG = "OneHandedGestureHandler";
private static final boolean DEBUG_GESTURE = false;
@@ -87,8 +87,8 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback,
* Constructor of OneHandedGestureHandler, we only handle the gesture of
* {@link Display#DEFAULT_DISPLAY}
*
- * @param context {@link Context}
- * @param displayController {@link DisplayController}
+ * @param context {@link Context}
+ * @param displayController {@link DisplayController}
* @param navigationModeController {@link NavigationModeController}
*/
@Inject
@@ -103,7 +103,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback,
mDragDistThreshold = context.getResources().getDimensionPixelSize(
R.dimen.gestures_onehanded_drag_threshold);
final float slop = ViewConfiguration.get(context).getScaledTouchSlop();
- mSquaredSlop = slop * slop;
+ mSquaredSlop = slop * slop;
updateIsEnabled();
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
index 70a81aaed249..51e587586852 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
@@ -57,6 +57,7 @@ public class OneHandedManagerImpl implements OneHandedManager, Dumpable {
private final OneHandedGestureHandler mGestureHandler;
private final OneHandedTimeoutHandler mTimeoutHandler;
private final OneHandedTouchHandler mTouchHandler;
+ private final OneHandedTutorialHandler mTutorialHandler;
private final SysUiState mSysUiFlagContainer;
private Context mContext;
@@ -107,6 +108,7 @@ public class OneHandedManagerImpl implements OneHandedManager, Dumpable {
DisplayController displayController,
OneHandedDisplayAreaOrganizer displayAreaOrganizer,
OneHandedTouchHandler touchHandler,
+ OneHandedTutorialHandler tutorialHandler,
OneHandedGestureHandler gestureHandler,
SysUiState sysUiState) {
mContext = context;
@@ -120,6 +122,7 @@ public class OneHandedManagerImpl implements OneHandedManager, Dumpable {
context.getContentResolver());
mTimeoutHandler = OneHandedTimeoutHandler.get();
mTouchHandler = touchHandler;
+ mTutorialHandler = tutorialHandler;
mGestureHandler = gestureHandler;
updateOneHandedEnabled();
setupGestures();
@@ -230,6 +233,7 @@ public class OneHandedManagerImpl implements OneHandedManager, Dumpable {
mDisplayAreaOrganizer.registerTransitionCallback(mTransitionCallback);
mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mGestureHandler);
+ mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java
index 3d4338c1e220..d616a3a45b90 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java
@@ -58,6 +58,7 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback, Dumpa
OneHandedTouchEventCallback mTouchEventCallback;
private boolean mIsEnabled;
+ private boolean mIsOnStopTransitioning;
private boolean mIsInOutsideRegion;
@Inject
@@ -96,8 +97,9 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback, Dumpa
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
mTimeoutHandler.resetTimer();
- if (mIsInOutsideRegion) {
+ if (mIsInOutsideRegion && !mIsOnStopTransitioning) {
mTouchEventCallback.onStop();
+ mIsOnStopTransitioning = true;
}
// Reset flag for next operation
mIsInOutsideRegion = false;
@@ -146,6 +148,7 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback, Dumpa
@Override
public void onStopFinished(Rect bounds) {
mLastUpdatedBounds.set(bounds);
+ mIsOnStopTransitioning = false;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
new file mode 100644
index 000000000000..8a67da53e6a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
@@ -0,0 +1,161 @@
+/*
+ * 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.systemui.onehanded;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+
+import com.android.systemui.Dumpable;
+import com.android.systemui.R;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Manages the user tutorial handling for One Handed operations, including animations synchronized
+ * with one-handed translation.
+ * Refer {@link OneHandedGestureHandler} and {@link OneHandedTouchHandler} to see start and stop
+ * one handed gesture
+ */
+@Singleton
+public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Dumpable {
+ private static final String TAG = "OneHandedTutorialHandler";
+ private final Rect mLastUpdatedBounds = new Rect();
+ private final WindowManager mWindowManager;
+
+ private View mTutorialView;
+ private Point mDisplaySize = new Point();
+ private Handler mUpdateHandler;
+
+ /**
+ * Container of the tutorial panel showing at outside region when one handed starting
+ */
+ private ViewGroup mTargetViewContainer;
+ private int mTutorialAreaHeight;
+
+ private final OneHandedAnimationCallback mAnimationCallback = new OneHandedAnimationCallback() {
+ @Override
+ public void onTutorialAnimationUpdate(int offset) {
+ mUpdateHandler.post(() -> onAnimationUpdate(offset));
+ }
+ };
+
+ @Inject
+ public OneHandedTutorialHandler(Context context) {
+ context.getDisplay().getRealSize(mDisplaySize);
+ mUpdateHandler = new Handler();
+ mWindowManager = context.getSystemService(WindowManager.class);
+ mTargetViewContainer = new FrameLayout(context);
+ mTargetViewContainer.setClipChildren(false);
+ mTutorialAreaHeight = Math.round(mDisplaySize.y * context.getResources().getFraction(
+ R.fraction.config_one_handed_offset, 1, 1));
+ mTutorialView = LayoutInflater.from(context).inflate(R.xml.one_handed_tutorial, null);
+ mTargetViewContainer.addView(mTutorialView);
+ createOrUpdateTutorialTarget();
+ }
+
+ @Override
+ public void onStartFinished(Rect bounds) {
+ mUpdateHandler.post(() -> updateFinished(View.VISIBLE, 0f));
+ }
+
+ @Override
+ public void onStopFinished(Rect bounds) {
+ mUpdateHandler.post(() -> updateFinished(
+ View.INVISIBLE, -mTargetViewContainer.getHeight()));
+ }
+
+ private void updateFinished(int visible, float finalPosition) {
+ mTargetViewContainer.setVisibility(visible);
+ mTargetViewContainer.setTranslationY(finalPosition);
+ }
+
+ /**
+ * Adds the tutorial target view to the WindowManager and update its layout, so it's ready
+ * to be animated in.
+ */
+ private void createOrUpdateTutorialTarget() {
+ mUpdateHandler.post(() -> {
+ if (!mTargetViewContainer.isAttachedToWindow()) {
+ mTargetViewContainer.setVisibility(View.INVISIBLE);
+
+ try {
+ mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams());
+ } catch (IllegalStateException e) {
+ // This shouldn't happen, but if the target is already added, just update its
+ // layout params.
+ mWindowManager.updateViewLayout(
+ mTargetViewContainer, getTutorialTargetLayoutParams());
+ }
+ } else {
+ mWindowManager.updateViewLayout(mTargetViewContainer,
+ getTutorialTargetLayoutParams());
+ }
+ });
+ }
+
+ OneHandedAnimationCallback getAnimationCallback() {
+ return mAnimationCallback;
+ }
+
+ /**
+ * Returns layout params for the dismiss target, using the latest display metrics.
+ */
+ private WindowManager.LayoutParams getTutorialTargetLayoutParams() {
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ mDisplaySize.x, mTutorialAreaHeight, 0, 0,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.TRANSLUCENT);
+ lp.gravity = Gravity.TOP | Gravity.LEFT;
+ lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+ lp.setFitInsetsTypes(0 /* types */);
+ lp.setTitle("one-handed-tutorial-overlay");
+
+ return lp;
+ }
+
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ final String innerPrefix = " ";
+ pw.println(TAG + "states: ");
+ pw.print(innerPrefix + "mLastUpdatedBounds=");
+ pw.println(mLastUpdatedBounds);
+ }
+
+ private void onAnimationUpdate(float value) {
+ mTargetViewContainer.setVisibility(View.VISIBLE);
+ mTargetViewContainer.setTransitionGroup(true);
+ mTargetViewContainer.setTranslationY(value - mTargetViewContainer.getHeight());
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
index 72019315139b..4931388fe362 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
@@ -53,16 +53,16 @@ public class PipAnimationController {
public static final int TRANSITION_DIRECTION_NONE = 0;
public static final int TRANSITION_DIRECTION_SAME = 1;
public static final int TRANSITION_DIRECTION_TO_PIP = 2;
- public static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3;
- public static final int TRANSITION_DIRECTION_TO_SPLIT_SCREEN = 4;
+ public static final int TRANSITION_DIRECTION_LEAVE_PIP = 3;
+ public static final int TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN = 4;
public static final int TRANSITION_DIRECTION_REMOVE_STACK = 5;
@IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = {
TRANSITION_DIRECTION_NONE,
TRANSITION_DIRECTION_SAME,
TRANSITION_DIRECTION_TO_PIP,
- TRANSITION_DIRECTION_TO_FULLSCREEN,
- TRANSITION_DIRECTION_TO_SPLIT_SCREEN,
+ TRANSITION_DIRECTION_LEAVE_PIP,
+ TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN,
TRANSITION_DIRECTION_REMOVE_STACK
})
@Retention(RetentionPolicy.SOURCE)
@@ -73,8 +73,8 @@ public class PipAnimationController {
}
public static boolean isOutPipDirection(@TransitionDirection int direction) {
- return direction == TRANSITION_DIRECTION_TO_FULLSCREEN
- || direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
+ return direction == TRANSITION_DIRECTION_LEAVE_PIP
+ || direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN;
}
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 312d6d62128f..7c3743bd8bcf 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -23,12 +23,12 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA;
import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_BOUNDS;
+import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP;
+import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_NONE;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_SAME;
-import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
-import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
import static com.android.systemui.pip.PipAnimationController.isInPipDirection;
import static com.android.systemui.pip.PipAnimationController.isOutPipDirection;
@@ -285,8 +285,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements
final WindowContainerTransaction wct = new WindowContainerTransaction();
final Rect destinationBounds = initialConfig.windowConfiguration.getBounds();
final int direction = syncWithSplitScreenBounds(destinationBounds)
- ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
- : TRANSITION_DIRECTION_TO_FULLSCREEN;
+ ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
+ : TRANSITION_DIRECTION_LEAVE_PIP;
if (orientationDiffers) {
// Send started callback though animation is ignored.
sendOnPipTransitionStarted(direction);
@@ -303,7 +303,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements
mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
mLastReportedBounds);
tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
- wct.setActivityWindowingMode(mToken, direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN
+ // We set to fullscreen here for now, but later it will be set to UNDEFINED for
+ // the proper windowing mode to take place. See #applyWindowingModeChangeOnExit.
+ wct.setActivityWindowingMode(mToken,
+ direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
: WINDOWING_MODE_FULLSCREEN);
wct.setBounds(mToken, destinationBounds);
@@ -327,7 +330,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements
wct.setWindowingMode(mToken, getOutPipWindowingMode());
// Simply reset the activity mode set prior to the animation running.
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- if (mSplitDivider != null && direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN) {
+ if (mSplitDivider != null && direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */);
}
}
@@ -842,7 +845,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements
} else if (isOutPipDirection(direction)) {
// If we are animating to fullscreen, then we need to reset the override bounds
// on the task to ensure that the task "matches" the parent's bounds.
- taskBounds = (direction == TRANSITION_DIRECTION_TO_FULLSCREEN)
+ taskBounds = (direction == TRANSITION_DIRECTION_LEAVE_PIP)
? null : destinationBounds;
applyWindowingModeChangeOnExit(wct, direction);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
index c715398d52da..a13318990f40 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
@@ -131,7 +131,7 @@ public class PipAccessibilityInteractionConnection
result = true;
break;
case AccessibilityNodeInfo.ACTION_EXPAND:
- mMotionHelper.expandPipToFullscreen();
+ mMotionHelper.expandLeavePip();
result = true;
break;
default:
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 582cd046f9e0..6e75253d8604 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -47,6 +47,7 @@ import com.android.systemui.pip.BasePipManager;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
@@ -181,7 +182,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
!= WINDOWING_MODE_PINNED) {
return;
}
- mTouchHandler.getMotionHelper().expandPipToFullscreen(clearedTask /* skipAnimation */);
+ mTouchHandler.getMotionHelper().expandLeavePip(clearedTask /* skipAnimation */);
}
};
@@ -250,6 +251,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
@Inject
public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
+ @PipMenuActivityClass Class<?> pipMenuActivityClass,
DisplayController displayController,
FloatingContentCoordinator floatingContentCoordinator,
DeviceConfigProxy deviceConfig,
@@ -274,8 +276,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mPipTaskOrganizer.registerPipTransitionCallback(this);
mInputConsumerController = InputConsumerController.getPipInputConsumer();
mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
- mMenuController = new PipMenuActivityController(context, mMediaController,
- mInputConsumerController);
+ mMenuController = new PipMenuActivityController(context, pipMenuActivityClass,
+ mMediaController, mInputConsumerController);
mTouchHandler = new PipTouchHandler(context, mActivityManager,
mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
floatingContentCoordinator, deviceConfig, pipSnapAlgorithm, sysUiState);
@@ -318,7 +320,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
*/
@Override
public void expandPip() {
- mTouchHandler.getMotionHelper().expandPipToFullscreen(false /* skipAnimation */);
+ mTouchHandler.getMotionHelper().expandLeavePip(false /* skipAnimation */);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index d6f3e163ad70..1b1b2de05883 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -76,17 +76,15 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.android.systemui.Interpolators;
-import com.android.systemui.SystemUIFactory;
import com.android.wm.shell.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import javax.inject.Inject;
-
/**
* Translucent activity that gets started on top of a task in PIP to allow the user to control it.
+ * TODO(b/150319024): PipMenuActivity will move to a Window
*/
public class PipMenuActivity extends Activity {
@@ -126,19 +124,11 @@ public class PipMenuActivity extends Activity {
private final List<RemoteAction> mActions = new ArrayList<>();
private AccessibilityManager mAccessibilityManager;
- private View mViewRoot;
private Drawable mBackgroundDrawable;
private View mMenuContainer;
private LinearLayout mActionsGroup;
- private View mSettingsButton;
- private View mDismissButton;
- private View mResizeHandle;
- private View mTopEndContainer;
private int mBetweenActionPaddingLand;
- @Inject
- PipMenuIconsAlgorithm mPipMenuIconsAlgorithm;
-
private AnimatorSet mMenuContainerAnimator;
private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener =
@@ -193,6 +183,9 @@ public class PipMenuActivity extends Activity {
break;
}
case MESSAGE_MENU_EXPANDED : {
+ if (mMenuContainerAnimator == null) {
+ return;
+ }
mMenuContainerAnimator.setStartDelay(MENU_SHOW_ON_EXPAND_START_DELAY);
mMenuContainerAnimator.start();
break;
@@ -202,6 +195,9 @@ public class PipMenuActivity extends Activity {
break;
}
case MESSAGE_UPDATE_MENU_LAYOUT: {
+ if (mPipMenuIconsAlgorithm == null) {
+ return;
+ }
final Rect bounds = (Rect) msg.obj;
mPipMenuIconsAlgorithm.onBoundsChanged(bounds);
break;
@@ -214,6 +210,13 @@ public class PipMenuActivity extends Activity {
private final Runnable mFinishRunnable = this::hideMenu;
+ protected View mViewRoot;
+ protected View mSettingsButton;
+ protected View mDismissButton;
+ protected View mResizeHandle;
+ protected View mTopEndContainer;
+ protected PipMenuIconsAlgorithm mPipMenuIconsAlgorithm;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// Set the flags to allow us to watch for outside touches and also hide the menu and start
@@ -222,8 +225,6 @@ public class PipMenuActivity extends Activity {
super.onCreate(savedInstanceState);
- SystemUIFactory.getInstance().getRootComponent().inject(this);
-
setContentView(R.layout.pip_menu_activity);
mAccessibilityManager = getSystemService(AccessibilityManager.class);
@@ -254,7 +255,7 @@ public class PipMenuActivity extends Activity {
mActionsGroup = findViewById(R.id.actions_group);
mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
R.dimen.pip_between_action_padding_land);
-
+ mPipMenuIconsAlgorithm = new PipMenuIconsAlgorithm(this.getApplicationContext());
mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer,
mResizeHandle, mSettingsButton, mDismissButton);
updateFromIntent(getIntent());
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 267c5eacd139..383f6b3bf79d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -110,6 +110,8 @@ public class PipMenuActivityController {
void onPipShowMenu();
}
+ /** TODO(b/150319024): PipMenuActivity will move to a Window */
+ private Class<?> mPipMenuActivityClass;
private Context mContext;
private PipMediaController mMediaController;
private InputConsumerController mInputConsumerController;
@@ -185,11 +187,13 @@ public class PipMenuActivityController {
}
};
- public PipMenuActivityController(Context context,
- PipMediaController mediaController, InputConsumerController inputConsumerController) {
+ public PipMenuActivityController(Context context, Class<?> pipMenuActivityClass,
+ PipMediaController mediaController, InputConsumerController inputConsumerController
+ ) {
mContext = context;
mMediaController = mediaController;
mInputConsumerController = inputConsumerController;
+ mPipMenuActivityClass = pipMenuActivityClass;
}
public boolean isMenuActivityVisible() {
@@ -454,7 +458,7 @@ public class PipMenuActivityController {
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
pinnedStackInfo.taskIds.length > 0) {
- Intent intent = new Intent(mContext, PipMenuActivity.class);
+ Intent intent = new Intent(mContext, mPipMenuActivityClass);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger);
intent.putExtra(EXTRA_ACTIONS, resolveMenuActions());
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java
index 69a04d8d3e22..6cfed070198b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuIconsAlgorithm.java
@@ -24,8 +24,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
-import javax.inject.Inject;
-
/**
* Helper class to calculate and place the menu icons on the PIP Menu.
*/
@@ -40,8 +38,7 @@ public class PipMenuIconsAlgorithm {
protected View mSettingsButton;
protected View mDismissButton;
- @Inject
- public PipMenuIconsAlgorithm(Context context) {
+ protected PipMenuIconsAlgorithm(Context context) {
}
/**
@@ -56,7 +53,6 @@ public class PipMenuIconsAlgorithm {
mDismissButton = dismissButton;
}
-
/**
* Updates the position of the drag handle based on where the PIP window is on the screen.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index ca3ef2465498..ee8f295e0c30 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -54,7 +54,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
- private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 300;
+ private static final int LEAVE_PIP_DURATION = 300;
private static final int SHIFT_DURATION = 300;
/** Friction to use for PIP when it moves via physics fling animations. */
@@ -304,16 +304,18 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
}
/**
- * Resizes the pinned stack back to fullscreen.
+ * Resizes the pinned stack back to unknown windowing mode, which could be freeform or
+ * * fullscreen depending on the display area's windowing mode.
*/
- void expandPipToFullscreen() {
- expandPipToFullscreen(false /* skipAnimation */);
+ void expandLeavePip() {
+ expandLeavePip(false /* skipAnimation */);
}
/**
- * Resizes the pinned stack back to fullscreen.
+ * Resizes the pinned stack back to unknown windowing mode, which could be freeform or
+ * fullscreen depending on the display area's windowing mode.
*/
- void expandPipToFullscreen(boolean skipAnimation) {
+ void expandLeavePip(boolean skipAnimation) {
if (DEBUG) {
Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
+ " callers=\n" + Debug.getCallers(5, " "));
@@ -323,7 +325,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
mPipTaskOrganizer.getUpdateHandler().post(() -> {
mPipTaskOrganizer.exitPip(skipAnimation
? 0
- : EXPAND_STACK_TO_FULLSCREEN_DURATION);
+ : LEAVE_PIP_DURATION);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 5434b62e19b8..7fc2823fc248 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -193,7 +193,7 @@ public class PipTouchHandler {
@Override
public void onPipExpand() {
- mMotionHelper.expandPipToFullscreen();
+ mMotionHelper.expandLeavePip();
}
@Override
@@ -991,7 +991,7 @@ public class PipTouchHandler {
// Expand to fullscreen if this is a double tap
// the PiP should be frozen until the transition ends
setTouchEnabled(false);
- mMotionHelper.expandPipToFullscreen();
+ mMotionHelper.expandLeavePip();
} else if (mMenuState != MENU_STATE_FULL) {
if (!mTouchState.isWaitingForDoubleTap()) {
// User has stalled long enough for this not to be a drag or a double tap, just
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java b/packages/SystemUI/src/com/android/systemui/pip/phone/dagger/PipMenuActivityClass.java
index 433114224289..114c30e625aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/dagger/PipMenuActivityClass.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.row.dagger;
+package com.android.systemui.pip.phone.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -26,5 +26,5 @@ import javax.inject.Qualifier;
@Qualifier
@Documented
@Retention(RUNTIME)
-public @interface DismissRunnable {
+public @interface PipMenuActivityClass {
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 5f37cc4520a3..df61fd19ad45 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -65,10 +65,6 @@ public class Recents extends SystemUI implements CommandQueue.Callbacks {
}
}
- public void growRecents() {
- mImpl.growRecents();
- }
-
@Override
public void showRecentApps(boolean triggeredFromAltTab) {
// Ensure the device has been provisioned before allowing the user to interact with
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
index 6f5ceabcc9a5..6d1299ba98ac 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
@@ -205,7 +205,8 @@ public class ScreenshotNotificationsController {
mPublicNotificationBuilder
.setContentTitle(mResources.getString(R.string.screenshot_saved_title))
.setContentText(mResources.getString(R.string.screenshot_saved_text))
- .setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
+ .setContentIntent(PendingIntent
+ .getActivity(mContext, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE))
.setWhen(now)
.setAutoCancel(true)
.setColor(mContext.getColor(
@@ -213,7 +214,8 @@ public class ScreenshotNotificationsController {
mNotificationBuilder
.setContentTitle(mResources.getString(R.string.screenshot_saved_title))
.setContentText(mResources.getString(R.string.screenshot_saved_text))
- .setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
+ .setContentIntent(PendingIntent
+ .getActivity(mContext, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE))
.setWhen(now)
.setAutoCancel(true)
.setColor(mContext.getColor(
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index eb7231211ea8..4007abb39903 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -16,559 +16,127 @@
package com.android.systemui.stackdivider;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.Display.DEFAULT_DISPLAY;
-
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.provider.Settings;
-import android.util.Slog;
-import android.view.LayoutInflater;
-import android.view.View;
import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-import android.window.WindowOrganizer;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.recents.Recents;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.wm.shell.common.DisplayChangeController;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.SystemWindows;
-import com.android.wm.shell.common.TransactionPool;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Optional;
import java.util.function.Consumer;
import javax.inject.Singleton;
-import dagger.Lazy;
-
/**
* Controls the docked stack divider.
*/
@Singleton
-public class Divider extends SystemUI implements DividerView.DividerCallbacks,
- DisplayController.OnDisplaysChangedListener {
- private static final String TAG = "Divider";
-
- static final boolean DEBUG = false;
-
- static final int DEFAULT_APP_TRANSITION_DURATION = 336;
-
- private final Optional<Lazy<Recents>> mRecentsOptionalLazy;
-
- private DividerWindowManager mWindowManager;
- private DividerView mView;
- private final DividerState mDividerState = new DividerState();
- private boolean mVisible = false;
- private boolean mMinimized = false;
- private boolean mAdjustedForIme = false;
- private boolean mHomeStackResizable = false;
- private ForcedResizableInfoActivityController mForcedResizableController;
- private SystemWindows mSystemWindows;
- private DisplayController mDisplayController;
- private DisplayImeController mImeController;
- final TransactionPool mTransactionPool;
-
- // Keeps track of real-time split geometry including snap positions and ime adjustments
- private SplitDisplayLayout mSplitLayout;
-
- // Transient: this contains the layout calculated for a new rotation requested by WM. This is
- // kept around so that we can wait for a matching configuration change and then use the exact
- // layout that we sent back to WM.
- private SplitDisplayLayout mRotateSplitLayout;
+public class Divider extends SystemUI {
+ private final KeyguardStateController mKeyguardStateController;
+ private final DividerController mDividerController;
- private Handler mHandler;
- private KeyguardStateController mKeyguardStateController;
-
- private WindowManagerProxy mWindowManagerProxy;
-
- private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
- new ArrayList<>();
-
- private SplitScreenTaskOrganizer mSplits = new SplitScreenTaskOrganizer(this);
-
- private DisplayChangeController.OnDisplayChangingListener mRotationController =
- (display, fromRotation, toRotation, wct) -> {
- if (!mSplits.isSplitScreenSupported() || mWindowManagerProxy == null) {
- return;
- }
- WindowContainerTransaction t = new WindowContainerTransaction();
- DisplayLayout displayLayout =
- new DisplayLayout(mDisplayController.getDisplayLayout(display));
- SplitDisplayLayout sdl = new SplitDisplayLayout(mContext, displayLayout, mSplits);
- sdl.rotateTo(toRotation);
- mRotateSplitLayout = sdl;
- final int position = isDividerVisible()
- ? (mMinimized ? mView.mSnapTargetBeforeMinimized.position
- : mView.getCurrentPosition())
- // snap resets to middle target when not in split-mode
- : sdl.getSnapAlgorithm().getMiddleTarget().position;
- DividerSnapAlgorithm snap = sdl.getSnapAlgorithm();
- final DividerSnapAlgorithm.SnapTarget target =
- snap.calculateNonDismissingSnapTarget(position);
- sdl.resizeSplits(target.position, t);
-
- if (isSplitActive() && mHomeStackResizable) {
- WindowManagerProxy.applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
- }
- if (mWindowManagerProxy.queueSyncTransactionIfWaiting(t)) {
- // Because sync transactions are serialized, its possible for an "older"
- // bounds-change to get applied after a screen rotation. In that case, we
- // want to actually defer on that rather than apply immediately. Of course,
- // this means that the bounds may not change until after the rotation so
- // the user might see some artifacts. This should be rare.
- Slog.w(TAG, "Screen rotated while other operations were pending, this may"
- + " result in some graphical artifacts.");
- } else {
- wct.merge(t, true /* transfer */);
- }
- };
-
- private final DividerImeController mImePositionProcessor;
-
- private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() {
- @Override
- public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
- boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
- if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
- != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || !mSplits.isSplitScreenSupported()) {
- return;
- }
-
- if (isMinimized()) {
- onUndockingTask();
- }
- }
- };
-
- public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
- DisplayController displayController, SystemWindows systemWindows,
- DisplayImeController imeController, Handler handler,
- KeyguardStateController keyguardStateController, TransactionPool transactionPool) {
+ Divider(Context context, DividerController dividerController,
+ KeyguardStateController keyguardStateController) {
super(context);
- mDisplayController = displayController;
- mSystemWindows = systemWindows;
- mImeController = imeController;
- mHandler = handler;
+ mDividerController = dividerController;
mKeyguardStateController = keyguardStateController;
- mRecentsOptionalLazy = recentsOptionalLazy;
- mForcedResizableController = new ForcedResizableInfoActivityController(context, this);
- mTransactionPool = transactionPool;
- mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler);
- mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler);
}
@Override
public void start() {
- mWindowManager = new DividerWindowManager(mSystemWindows);
- mDisplayController.addDisplayWindowListener(this);
+ mDividerController.start();
// Hide the divider when keyguard is showing. Even though keyguard/statusbar is above
// everything, it is actually transparent except for notifications, so we still need to
// hide any surfaces that are below it.
// TODO(b/148906453): Figure out keyguard dismiss animation for divider view.
mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
- public void onUnlockedChanged() {
-
- }
-
- @Override
public void onKeyguardShowingChanged() {
- if (!isSplitActive() || mView == null) {
- return;
- }
- mView.setHidden(mKeyguardStateController.isShowing());
- if (!mKeyguardStateController.isShowing()) {
- mImePositionProcessor.updateAdjustForIme();
- }
- }
-
- @Override
- public void onKeyguardFadingAwayChanged() {
-
+ mDividerController.onKeyguardShowingChanged(mKeyguardStateController.isShowing());
}
});
// Don't initialize the divider or anything until we get the default display.
- }
- @Override
- public void onDisplayAdded(int displayId) {
- if (displayId != DEFAULT_DISPLAY) {
- return;
- }
- mSplitLayout = new SplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
- mDisplayController.getDisplayLayout(displayId), mSplits);
- mImeController.addPositionProcessor(mImePositionProcessor);
- mDisplayController.addDisplayChangingController(mRotationController);
- if (!ActivityTaskManager.supportsSplitScreenMultiWindow(mContext)) {
- removeDivider();
- return;
- }
- try {
- mSplits.init();
- // Set starting tile bounds based on middle target
- final WindowContainerTransaction tct = new WindowContainerTransaction();
- int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
- mSplitLayout.resizeSplits(midPos, tct);
- WindowOrganizer.applyTransaction(tct);
- } catch (Exception e) {
- Slog.e(TAG, "Failed to register docked stack listener", e);
- removeDivider();
- return;
- }
- ActivityManagerWrapper.getInstance().registerTaskStackListener(mActivityRestartListener);
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(
+ new TaskStackChangeListener() {
+ @Override
+ public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ if (!wasVisible || task.configuration.windowConfiguration.getWindowingMode()
+ != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
+ || !mDividerController.isSplitScreenSupported()) {
+ return;
+ }
+
+ if (mDividerController.isMinimized()) {
+ onUndockingTask();
+ }
+ }
+ }
+ );
}
@Override
- public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
- if (displayId != DEFAULT_DISPLAY || !mSplits.isSplitScreenSupported()) {
- return;
- }
- mSplitLayout = new SplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
- mDisplayController.getDisplayLayout(displayId), mSplits);
- if (mRotateSplitLayout == null) {
- int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
- final WindowContainerTransaction tct = new WindowContainerTransaction();
- mSplitLayout.resizeSplits(midPos, tct);
- WindowOrganizer.applyTransaction(tct);
- } else if (mSplitLayout.mDisplayLayout.rotation()
- == mRotateSplitLayout.mDisplayLayout.rotation()) {
- mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
- mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
- mRotateSplitLayout = null;
- }
- if (isSplitActive()) {
- update(newConfig);
- }
- }
-
- Handler getHandler() {
- return mHandler;
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mDividerController.dump(pw);
}
- public DividerView getView() {
- return mView;
+ /** Switch to minimized state if appropriate. */
+ public void setMinimized(final boolean minimized) {
+ mDividerController.setMinimized(minimized);
}
public boolean isMinimized() {
- return mMinimized;
+ return mDividerController.isMinimized();
}
public boolean isHomeStackResizable() {
- return mHomeStackResizable;
- }
-
- /** {@code true} if this is visible */
- public boolean isDividerVisible() {
- return mView != null && mView.getVisibility() == View.VISIBLE;
- }
-
- /**
- * This indicates that at-least one of the splits has content. This differs from
- * isDividerVisible because the divider is only visible once *everything* is in split mode
- * while this only cares if some things are (eg. while entering/exiting as well).
- */
- private boolean isSplitActive() {
- return mSplits.mPrimary != null && mSplits.mSecondary != null
- && (mSplits.mPrimary.topActivityType != ACTIVITY_TYPE_UNDEFINED
- || mSplits.mSecondary.topActivityType != ACTIVITY_TYPE_UNDEFINED);
- }
-
- private void addDivider(Configuration configuration) {
- Context dctx = mDisplayController.getDisplayContext(mContext.getDisplayId());
- mView = (DividerView)
- LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
- DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
- mView.injectDependencies(mWindowManager, mDividerState, this, mSplits, mSplitLayout,
- mImePositionProcessor, mWindowManagerProxy);
- mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
- mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, null /* transaction */);
- final int size = dctx.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.docked_stack_divider_thickness);
- final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
- final int width = landscape ? size : displayLayout.width();
- final int height = landscape ? displayLayout.height() : size;
- mWindowManager.add(mView, width, height, mContext.getDisplayId());
- }
-
- private void removeDivider() {
- if (mView != null) {
- mView.onDividerRemoved();
- }
- mWindowManager.remove();
- }
-
- private void update(Configuration configuration) {
- final boolean isDividerHidden = mView != null && mKeyguardStateController.isShowing();
-
- removeDivider();
- addDivider(configuration);
-
- if (mMinimized) {
- mView.setMinimizedDockStack(true, mHomeStackResizable, null /* transaction */);
- updateTouchable();
- }
- mView.setHidden(isDividerHidden);
- }
-
- void onTaskVanished() {
- mHandler.post(this::removeDivider);
- }
-
- private void updateVisibility(final boolean visible) {
- if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible);
- if (mVisible != visible) {
- mVisible = visible;
- mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
-
- if (visible) {
- mView.enterSplitMode(mHomeStackResizable);
- // Update state because animations won't finish.
- mWindowManagerProxy.runInSync(
- t -> mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, t));
-
- } else {
- mView.exitSplitMode();
- mWindowManagerProxy.runInSync(
- t -> mView.setMinimizedDockStack(false, mHomeStackResizable, t));
- }
- // Notify existence listeners
- synchronized (mDockedStackExistsListeners) {
- mDockedStackExistsListeners.removeIf(wf -> {
- Consumer<Boolean> l = wf.get();
- if (l != null) l.accept(visible);
- return l == null;
- });
- }
- }
+ return mDividerController.isHomeStackResizable();
}
- /** Switch to minimized state if appropriate */
- public void setMinimized(final boolean minimized) {
- if (DEBUG) Slog.d(TAG, "posting ext setMinimized " + minimized + " vis:" + mVisible);
- mHandler.post(() -> {
- if (DEBUG) Slog.d(TAG, "run posted ext setMinimized " + minimized + " vis:" + mVisible);
- if (!mVisible) {
- return;
- }
- setHomeMinimized(minimized, mHomeStackResizable);
- });
- }
-
- private void setHomeMinimized(final boolean minimized, boolean homeStackResizable) {
- if (DEBUG) {
- Slog.d(TAG, "setHomeMinimized min:" + mMinimized + "->" + minimized + " hrsz:"
- + mHomeStackResizable + "->" + homeStackResizable
- + " split:" + isDividerVisible());
- }
- WindowContainerTransaction wct = new WindowContainerTransaction();
- final boolean minimizedChanged = mMinimized != minimized;
- // Update minimized state
- if (minimizedChanged) {
- mMinimized = minimized;
- }
- // Always set this because we could be entering split when mMinimized is already true
- wct.setFocusable(mSplits.mPrimary.token, !mMinimized);
- boolean onlyFocusable = true;
-
- // Update home-stack resizability
- final boolean homeResizableChanged = mHomeStackResizable != homeStackResizable;
- if (homeResizableChanged) {
- mHomeStackResizable = homeStackResizable;
- if (isDividerVisible()) {
- WindowManagerProxy.applyHomeTasksMinimized(
- mSplitLayout, mSplits.mSecondary.token, wct);
- onlyFocusable = false;
- }
- }
-
- // Sync state to DividerView if it exists.
- if (mView != null) {
- final int displayId = mView.getDisplay() != null
- ? mView.getDisplay().getDisplayId() : DEFAULT_DISPLAY;
- // pause ime here (before updateMinimizedDockedStack)
- if (mMinimized) {
- mImePositionProcessor.pause(displayId);
- }
- if (minimizedChanged || homeResizableChanged) {
- // This conflicts with IME adjustment, so only call it when things change.
- mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable);
- }
- if (!mMinimized) {
- // afterwards so it can end any animations started in view
- mImePositionProcessor.resume(displayId);
- }
- }
- updateTouchable();
- if (onlyFocusable) {
- // If we are only setting focusability, a sync transaction isn't necessary (in fact it
- // can interrupt other animations), so see if it can be submitted on pending instead.
- if (!mSplits.mDivider.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
- WindowOrganizer.applyTransaction(wct);
- }
- } else {
- mWindowManagerProxy.applySyncTransaction(wct);
- }
- }
-
- void setAdjustedForIme(boolean adjustedForIme) {
- if (mAdjustedForIme == adjustedForIme) {
- return;
- }
- mAdjustedForIme = adjustedForIme;
- updateTouchable();
- }
-
- private void updateTouchable() {
- mWindowManager.setTouchable(!mAdjustedForIme);
+ /** Callback for undocking task. */
+ public void onUndockingTask() {
+ mDividerController.onUndockingTask();
}
- /**
- * Workaround for b/62528361, at the time recents has drawn, it may happen before a
- * configuration change to the Divider, and internally, the event will be posted to the
- * subscriber, or DividerView, which has been removed and prevented from resizing. Instead,
- * register the event handler here and proxy the event to the current DividerView.
- */
public void onRecentsDrawn() {
- if (mView != null) {
- mView.onRecentsDrawn();
- }
- }
-
- public void onUndockingTask() {
- if (mView != null) {
- mView.onUndockingTask();
- }
+ mDividerController.onRecentsDrawn();
}
public void onDockedFirstAnimationFrame() {
- if (mView != null) {
- mView.onDockedFirstAnimationFrame();
- }
+ mDividerController.onDockedFirstAnimationFrame();
}
public void onDockedTopTask() {
- if (mView != null) {
- mView.onDockedTopTask();
- }
+ mDividerController.onDockedTopTask();
}
public void onAppTransitionFinished() {
- if (mView == null) {
- return;
- }
- mForcedResizableController.onAppTransitionFinished();
+ mDividerController.onAppTransitionFinished();
}
- @Override
- public void onDraggingStart() {
- mForcedResizableController.onDraggingStart();
- }
-
- @Override
- public void onDraggingEnd() {
- mForcedResizableController.onDraggingEnd();
- }
-
- @Override
- public void growRecents() {
- mRecentsOptionalLazy.ifPresent(recentsLazy -> recentsLazy.get().growRecents());
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.print(" mVisible="); pw.println(mVisible);
- pw.print(" mMinimized="); pw.println(mMinimized);
- pw.print(" mAdjustedForIme="); pw.println(mAdjustedForIme);
+ public DividerView getView() {
+ return mDividerController.getDividerView();
}
- long getAnimDuration() {
- float transitionScale = Settings.Global.getFloat(mContext.getContentResolver(),
- Settings.Global.TRANSITION_ANIMATION_SCALE,
- mContext.getResources().getFloat(
- com.android.internal.R.dimen
- .config_appTransitionAnimationDurationScaleDefault));
- final long transitionDuration = DEFAULT_APP_TRANSITION_DURATION;
- return (long) (transitionDuration * transitionScale);
+ /** @return the container token for the secondary split root task. */
+ public WindowContainerToken getSecondaryRoot() {
+ return mDividerController.getSecondaryRoot();
}
/** Register a listener that gets called whenever the existence of the divider changes */
public void registerInSplitScreenListener(Consumer<Boolean> listener) {
- listener.accept(isDividerVisible());
- synchronized (mDockedStackExistsListeners) {
- mDockedStackExistsListeners.add(new WeakReference<>(listener));
- }
- }
-
- void startEnterSplit() {
- update(mDisplayController.getDisplayContext(
- mContext.getDisplayId()).getResources().getConfiguration());
- // Set resizable directly here because applyEnterSplit already resizes home stack.
- mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
- }
-
- void startDismissSplit() {
- mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, true /* dismissOrMaximize */);
- updateVisibility(false /* visible */);
- mMinimized = false;
- removeDivider();
- mImePositionProcessor.reset();
+ mDividerController.registerInSplitScreenListener(listener);
}
- void ensureMinimizedSplit() {
- setHomeMinimized(true /* minimized */, mHomeStackResizable);
- if (mView != null && !isDividerVisible()) {
- // Wasn't in split-mode yet, so enter now.
- if (DEBUG) {
- Slog.d(TAG, " entering split mode with minimized=true");
- }
- updateVisibility(true /* visible */);
- }
- }
-
- void ensureNormalSplit() {
- setHomeMinimized(false /* minimized */, mHomeStackResizable);
- if (mView != null && !isDividerVisible()) {
- // Wasn't in split-mode, so enter now.
- if (DEBUG) {
- Slog.d(TAG, " enter split mode unminimized ");
- }
- updateVisibility(true /* visible */);
- }
- }
-
- SplitDisplayLayout getSplitLayout() {
- return mSplitLayout;
- }
-
- WindowManagerProxy getWmProxy() {
- return mWindowManagerProxy;
- }
-
- /** @return the container token for the secondary split root task. */
- public WindowContainerToken getSecondaryRoot() {
- if (mSplits == null || mSplits.mSecondary == null) {
- return null;
- }
- return mSplits.mSecondary.token;
+ /** {@code true} if this is visible */
+ public boolean isDividerVisible() {
+ return mDividerController.isDividerVisible();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
new file mode 100644
index 000000000000..81649f608581
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerController.java
@@ -0,0 +1,516 @@
+/*
+ * 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.systemui.stackdivider;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.ActivityTaskManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+import android.window.WindowOrganizer;
+
+import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.systemui.R;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.TransactionPool;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Controls the docked stack divider.
+ */
+public class DividerController implements DividerView.DividerCallbacks,
+ DisplayController.OnDisplaysChangedListener {
+ static final boolean DEBUG = false;
+ private static final String TAG = "Divider";
+
+ static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+
+ private DividerWindowManager mWindowManager;
+ private DividerView mView;
+ private final DividerState mDividerState = new DividerState();
+ private boolean mVisible = false;
+ private boolean mMinimized = false;
+ private boolean mAdjustedForIme = false;
+ private boolean mHomeStackResizable = false;
+ private ForcedResizableInfoActivityController mForcedResizableController;
+ private SystemWindows mSystemWindows;
+ private DisplayController mDisplayController;
+ private DisplayImeController mImeController;
+ final TransactionPool mTransactionPool;
+
+ // Keeps track of real-time split geometry including snap positions and ime adjustments
+ private SplitDisplayLayout mSplitLayout;
+
+ // Transient: this contains the layout calculated for a new rotation requested by WM. This is
+ // kept around so that we can wait for a matching configuration change and then use the exact
+ // layout that we sent back to WM.
+ private SplitDisplayLayout mRotateSplitLayout;
+
+ private final Handler mHandler;
+ private final WindowManagerProxy mWindowManagerProxy;
+
+ private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
+ new ArrayList<>();
+
+ private final SplitScreenTaskOrganizer mSplits;
+ private final DisplayChangeController.OnDisplayChangingListener mRotationController;
+ private final DividerImeController mImePositionProcessor;
+ private final Context mContext;
+ private boolean mIsKeyguardShowing;
+
+ public DividerController(Context context,
+ DisplayController displayController, SystemWindows systemWindows,
+ DisplayImeController imeController, Handler handler, TransactionPool transactionPool) {
+ mContext = context;
+ mDisplayController = displayController;
+ mSystemWindows = systemWindows;
+ mImeController = imeController;
+ mHandler = handler;
+ mForcedResizableController = new ForcedResizableInfoActivityController(context, this);
+ mTransactionPool = transactionPool;
+ mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler);
+ mSplits = new SplitScreenTaskOrganizer(this);
+ mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler);
+ mRotationController =
+ (display, fromRotation, toRotation, wct) -> {
+ if (!mSplits.isSplitScreenSupported() || mWindowManagerProxy == null) {
+ return;
+ }
+ WindowContainerTransaction t = new WindowContainerTransaction();
+ DisplayLayout displayLayout =
+ new DisplayLayout(mDisplayController.getDisplayLayout(display));
+ SplitDisplayLayout sdl =
+ new SplitDisplayLayout(mContext, displayLayout, mSplits);
+ sdl.rotateTo(toRotation);
+ mRotateSplitLayout = sdl;
+ final int position = isDividerVisible()
+ ? (mMinimized ? mView.mSnapTargetBeforeMinimized.position
+ : mView.getCurrentPosition())
+ // snap resets to middle target when not in split-mode
+ : sdl.getSnapAlgorithm().getMiddleTarget().position;
+ DividerSnapAlgorithm snap = sdl.getSnapAlgorithm();
+ final DividerSnapAlgorithm.SnapTarget target =
+ snap.calculateNonDismissingSnapTarget(position);
+ sdl.resizeSplits(target.position, t);
+
+ if (isSplitActive() && mHomeStackResizable) {
+ WindowManagerProxy
+ .applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
+ }
+ if (mWindowManagerProxy.queueSyncTransactionIfWaiting(t)) {
+ // Because sync transactions are serialized, its possible for an "older"
+ // bounds-change to get applied after a screen rotation. In that case, we
+ // want to actually defer on that rather than apply immediately. Of course,
+ // this means that the bounds may not change until after the rotation so
+ // the user might see some artifacts. This should be rare.
+ Slog.w(TAG, "Screen rotated while other operations were pending, this may"
+ + " result in some graphical artifacts.");
+ } else {
+ wct.merge(t, true /* transfer */);
+ }
+ };
+ }
+
+ /** Inits the divider service. */
+ public void start() {
+ mWindowManager = new DividerWindowManager(mSystemWindows);
+ mDisplayController.addDisplayWindowListener(this);
+ // Don't initialize the divider or anything until we get the default display.
+ }
+
+ /** Returns {@code true} if split screen is supported on the device. */
+ public boolean isSplitScreenSupported() {
+ return mSplits.isSplitScreenSupported();
+ }
+
+ /** Called when keyguard showing state changed. */
+ public void onKeyguardShowingChanged(boolean isShowing) {
+ if (!isSplitActive() || mView == null) {
+ return;
+ }
+ mView.setHidden(isShowing);
+ if (!isShowing) {
+ mImePositionProcessor.updateAdjustForIme();
+ }
+ mIsKeyguardShowing = isShowing;
+ }
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
+ }
+ mSplitLayout = new SplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
+ mDisplayController.getDisplayLayout(displayId), mSplits);
+ mImeController.addPositionProcessor(mImePositionProcessor);
+ mDisplayController.addDisplayChangingController(mRotationController);
+ if (!ActivityTaskManager.supportsSplitScreenMultiWindow(mContext)) {
+ removeDivider();
+ return;
+ }
+ try {
+ mSplits.init();
+ // Set starting tile bounds based on middle target
+ final WindowContainerTransaction tct = new WindowContainerTransaction();
+ int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
+ mSplitLayout.resizeSplits(midPos, tct);
+ WindowOrganizer.applyTransaction(tct);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to register docked stack listener", e);
+ removeDivider();
+ return;
+ }
+ }
+
+ @Override
+ public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
+ if (displayId != DEFAULT_DISPLAY || !mSplits.isSplitScreenSupported()) {
+ return;
+ }
+ mSplitLayout = new SplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
+ mDisplayController.getDisplayLayout(displayId), mSplits);
+ if (mRotateSplitLayout == null) {
+ int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
+ final WindowContainerTransaction tct = new WindowContainerTransaction();
+ mSplitLayout.resizeSplits(midPos, tct);
+ WindowOrganizer.applyTransaction(tct);
+ } else if (mSplitLayout.mDisplayLayout.rotation()
+ == mRotateSplitLayout.mDisplayLayout.rotation()) {
+ mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
+ mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
+ mRotateSplitLayout = null;
+ }
+ if (isSplitActive()) {
+ update(newConfig);
+ }
+ }
+
+ /** Posts task to handler dealing with divider. */
+ void post(Runnable task) {
+ mHandler.post(task);
+ }
+
+ /** Returns {@link DividerView}. */
+ public DividerView getDividerView() {
+ return mView;
+ }
+
+ /** Returns {@code true} if one of the split screen is in minimized mode. */
+ public boolean isMinimized() {
+ return mMinimized;
+ }
+
+ public boolean isHomeStackResizable() {
+ return mHomeStackResizable;
+ }
+
+ /** Returns {@code true} if the divider is visible. */
+ public boolean isDividerVisible() {
+ return mView != null && mView.getVisibility() == View.VISIBLE;
+ }
+
+ /**
+ * This indicates that at-least one of the splits has content. This differs from
+ * isDividerVisible because the divider is only visible once *everything* is in split mode
+ * while this only cares if some things are (eg. while entering/exiting as well).
+ */
+ private boolean isSplitActive() {
+ return mSplits.mPrimary != null && mSplits.mSecondary != null
+ && (mSplits.mPrimary.topActivityType != ACTIVITY_TYPE_UNDEFINED
+ || mSplits.mSecondary.topActivityType != ACTIVITY_TYPE_UNDEFINED);
+ }
+
+ private void addDivider(Configuration configuration) {
+ Context dctx = mDisplayController.getDisplayContext(mContext.getDisplayId());
+ mView = (DividerView)
+ LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
+ DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
+ mView.injectDependencies(mWindowManager, mDividerState, this, mSplits, mSplitLayout,
+ mImePositionProcessor, mWindowManagerProxy);
+ mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
+ mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, null /* transaction */);
+ final int size = dctx.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.docked_stack_divider_thickness);
+ final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
+ final int width = landscape ? size : displayLayout.width();
+ final int height = landscape ? displayLayout.height() : size;
+ mWindowManager.add(mView, width, height, mContext.getDisplayId());
+ }
+
+ private void removeDivider() {
+ if (mView != null) {
+ mView.onDividerRemoved();
+ }
+ mWindowManager.remove();
+ }
+
+ private void update(Configuration configuration) {
+ final boolean isDividerHidden = mView != null && mIsKeyguardShowing;
+
+ removeDivider();
+ addDivider(configuration);
+
+ if (mMinimized) {
+ mView.setMinimizedDockStack(true, mHomeStackResizable, null /* transaction */);
+ updateTouchable();
+ }
+ mView.setHidden(isDividerHidden);
+ }
+
+ void onTaskVanished() {
+ mHandler.post(this::removeDivider);
+ }
+
+ private void updateVisibility(final boolean visible) {
+ if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible);
+ if (mVisible != visible) {
+ mVisible = visible;
+ mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+
+ if (visible) {
+ mView.enterSplitMode(mHomeStackResizable);
+ // Update state because animations won't finish.
+ mWindowManagerProxy.runInSync(
+ t -> mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, t));
+
+ } else {
+ mView.exitSplitMode();
+ mWindowManagerProxy.runInSync(
+ t -> mView.setMinimizedDockStack(false, mHomeStackResizable, t));
+ }
+ // Notify existence listeners
+ synchronized (mDockedStackExistsListeners) {
+ mDockedStackExistsListeners.removeIf(wf -> {
+ Consumer<Boolean> l = wf.get();
+ if (l != null) l.accept(visible);
+ return l == null;
+ });
+ }
+ }
+ }
+
+ /** Switch to minimized state if appropriate. */
+ public void setMinimized(final boolean minimized) {
+ if (DEBUG) Slog.d(TAG, "posting ext setMinimized " + minimized + " vis:" + mVisible);
+ mHandler.post(() -> {
+ if (DEBUG) Slog.d(TAG, "run posted ext setMinimized " + minimized + " vis:" + mVisible);
+ if (!mVisible) {
+ return;
+ }
+ setHomeMinimized(minimized);
+ });
+ }
+
+ private void setHomeMinimized(final boolean minimized) {
+ if (DEBUG) {
+ Slog.d(TAG, "setHomeMinimized min:" + mMinimized + "->" + minimized + " hrsz:"
+ + mHomeStackResizable + " split:" + isDividerVisible());
+ }
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ final boolean minimizedChanged = mMinimized != minimized;
+ // Update minimized state
+ if (minimizedChanged) {
+ mMinimized = minimized;
+ }
+ // Always set this because we could be entering split when mMinimized is already true
+ wct.setFocusable(mSplits.mPrimary.token, !mMinimized);
+
+ // Sync state to DividerView if it exists.
+ if (mView != null) {
+ final int displayId = mView.getDisplay() != null
+ ? mView.getDisplay().getDisplayId() : DEFAULT_DISPLAY;
+ // pause ime here (before updateMinimizedDockedStack)
+ if (mMinimized) {
+ mImePositionProcessor.pause(displayId);
+ }
+ if (minimizedChanged) {
+ // This conflicts with IME adjustment, so only call it when things change.
+ mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable);
+ }
+ if (!mMinimized) {
+ // afterwards so it can end any animations started in view
+ mImePositionProcessor.resume(displayId);
+ }
+ }
+ updateTouchable();
+
+ // If we are only setting focusability, a sync transaction isn't necessary (in fact it
+ // can interrupt other animations), so see if it can be submitted on pending instead.
+ if (!mWindowManagerProxy.queueSyncTransactionIfWaiting(wct)) {
+ WindowOrganizer.applyTransaction(wct);
+ }
+ }
+
+ void setAdjustedForIme(boolean adjustedForIme) {
+ if (mAdjustedForIme == adjustedForIme) {
+ return;
+ }
+ mAdjustedForIme = adjustedForIme;
+ updateTouchable();
+ }
+
+ private void updateTouchable() {
+ mWindowManager.setTouchable(!mAdjustedForIme);
+ }
+
+ /**
+ * Workaround for b/62528361, at the time recents has drawn, it may happen before a
+ * configuration change to the Divider, and internally, the event will be posted to the
+ * subscriber, or DividerView, which has been removed and prevented from resizing. Instead,
+ * register the event handler here and proxy the event to the current DividerView.
+ */
+ public void onRecentsDrawn() {
+ if (mView != null) {
+ mView.onRecentsDrawn();
+ }
+ }
+
+ /** Called when there's a task undocking. */
+ public void onUndockingTask() {
+ if (mView != null) {
+ mView.onUndockingTask();
+ }
+ }
+
+ /** Called when the first docked animation frame rendered. */
+ public void onDockedFirstAnimationFrame() {
+ if (mView != null) {
+ mView.onDockedFirstAnimationFrame();
+ }
+ }
+
+ /** Called when top task docked. */
+ public void onDockedTopTask() {
+ if (mView != null) {
+ mView.onDockedTopTask();
+ }
+ }
+
+ /** Called when app transition finished. */
+ public void onAppTransitionFinished() {
+ if (mView == null) {
+ return;
+ }
+ mForcedResizableController.onAppTransitionFinished();
+ }
+
+ @Override
+ public void onDraggingStart() {
+ mForcedResizableController.onDraggingStart();
+ }
+
+ @Override
+ public void onDraggingEnd() {
+ mForcedResizableController.onDraggingEnd();
+ }
+
+ /** Dumps current status of Divider.*/
+ public void dump(PrintWriter pw) {
+ pw.print(" mVisible="); pw.println(mVisible);
+ pw.print(" mMinimized="); pw.println(mMinimized);
+ pw.print(" mAdjustedForIme="); pw.println(mAdjustedForIme);
+ }
+
+ long getAnimDuration() {
+ float transitionScale = Settings.Global.getFloat(mContext.getContentResolver(),
+ Settings.Global.TRANSITION_ANIMATION_SCALE,
+ mContext.getResources().getFloat(
+ com.android.internal.R.dimen
+ .config_appTransitionAnimationDurationScaleDefault));
+ final long transitionDuration = DEFAULT_APP_TRANSITION_DURATION;
+ return (long) (transitionDuration * transitionScale);
+ }
+
+ /** Registers listener that gets called whenever the existence of the divider changes. */
+ public void registerInSplitScreenListener(Consumer<Boolean> listener) {
+ listener.accept(isDividerVisible());
+ synchronized (mDockedStackExistsListeners) {
+ mDockedStackExistsListeners.add(new WeakReference<>(listener));
+ }
+ }
+
+ void startEnterSplit() {
+ update(mDisplayController.getDisplayContext(
+ mContext.getDisplayId()).getResources().getConfiguration());
+ // Set resizable directly here because applyEnterSplit already resizes home stack.
+ mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
+ }
+
+ void startDismissSplit() {
+ mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, true /* dismissOrMaximize */);
+ updateVisibility(false /* visible */);
+ mMinimized = false;
+ removeDivider();
+ mImePositionProcessor.reset();
+ }
+
+ void ensureMinimizedSplit() {
+ setHomeMinimized(true /* minimized */);
+ if (mView != null && !isDividerVisible()) {
+ // Wasn't in split-mode yet, so enter now.
+ if (DEBUG) {
+ Slog.d(TAG, " entering split mode with minimized=true");
+ }
+ updateVisibility(true /* visible */);
+ }
+ }
+
+ void ensureNormalSplit() {
+ setHomeMinimized(false /* minimized */);
+ if (mView != null && !isDividerVisible()) {
+ // Wasn't in split-mode, so enter now.
+ if (DEBUG) {
+ Slog.d(TAG, " enter split mode unminimized ");
+ }
+ updateVisibility(true /* visible */);
+ }
+ }
+
+ SplitDisplayLayout getSplitLayout() {
+ return mSplitLayout;
+ }
+
+ WindowManagerProxy getWmProxy() {
+ return mWindowManagerProxy;
+ }
+
+ /** @return the container token for the secondary split root task. */
+ public WindowContainerToken getSecondaryRoot() {
+ if (mSplits == null || mSplits.mSecondary == null) {
+ return null;
+ }
+ return mSplits.mSecondary.token;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
index d5f7b39b8e61..a10242a689a2 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
@@ -34,7 +34,7 @@ import com.android.systemui.R;
/**
* View for the handle in the docked stack divider.
*/
-public class DividerHandleView extends View {
+class DividerHandleView extends View {
private final static Property<DividerHandleView, Integer> WIDTH_PROPERTY
= new Property<DividerHandleView, Integer>(Integer.class, "width") {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
index 84ec38744e98..c915f071297f 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
@@ -38,7 +38,7 @@ import com.android.wm.shell.common.TransactionPool;
class DividerImeController implements DisplayImeController.ImePositionProcessor {
private static final String TAG = "DividerImeController";
- private static final boolean DEBUG = Divider.DEBUG;
+ private static final boolean DEBUG = DividerController.DEBUG;
private static final float ADJUSTED_NONFOCUS_DIM = 0.3f;
@@ -100,15 +100,15 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
}
private DividerView getView() {
- return mSplits.mDivider.getView();
+ return mSplits.mDividerController.getDividerView();
}
private SplitDisplayLayout getLayout() {
- return mSplits.mDivider.getSplitLayout();
+ return mSplits.mDividerController.getSplitLayout();
}
private boolean isDividerVisible() {
- return mSplits.mDivider.isDividerVisible();
+ return mSplits.mDividerController.isDividerVisible();
}
private boolean getSecondaryHasFocus(int displayId) {
@@ -151,7 +151,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
&& !imeIsFloating && !getLayout().mDisplayLayout.isLandscape()
- && !mSplits.mDivider.isMinimized();
+ && !mSplits.mDividerController.isMinimized();
if (mLastAdjustTop < 0) {
mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
} else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) {
@@ -236,7 +236,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
}
- if (!mSplits.mDivider.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
+ if (!mSplits.mDividerController.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
WindowOrganizer.applyTransaction(wct);
}
}
@@ -250,7 +250,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
: DisplayImeController.ANIMATION_DURATION_HIDE_MS);
}
}
- mSplits.mDivider.setAdjustedForIme(mTargetShown && !mPaused);
+ mSplits.mDividerController.setAdjustedForIme(mTargetShown && !mPaused);
}
public void updateAdjustForIme() {
@@ -343,10 +343,12 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR);
mAnimation.addListener(new AnimatorListenerAdapter() {
private boolean mCancel = false;
+
@Override
public void onAnimationCancel(Animator animation) {
mCancel = true;
}
+
@Override
public void onAnimationEnd(Animator animation) {
SurfaceControl.Transaction t = mTransactionPool.acquire();
@@ -400,7 +402,8 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
mTargetAdjusted = mPausedTargetAdjusted;
updateDimTargets();
final DividerView view = getView();
- if ((mTargetAdjusted != mAdjusted) && !mSplits.mDivider.isMinimized() && view != null) {
+ if ((mTargetAdjusted != mAdjusted) && !mSplits.mDividerController.isMinimized()
+ && view != null) {
// End unminimize animations since they conflict with adjustment animations.
view.finishAnimations();
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
index c24431c22d62..db0aef8a0611 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
@@ -20,18 +20,14 @@ import android.content.Context;
import android.os.Handler;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.recents.Recents;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
-import java.util.Optional;
-
import javax.inject.Singleton;
-import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -42,11 +38,12 @@ import dagger.Provides;
public class DividerModule {
@Singleton
@Provides
- static Divider provideDivider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
- DisplayController displayController, SystemWindows systemWindows,
- DisplayImeController imeController, @Main Handler handler,
+ static Divider provideDivider(Context context, DisplayController displayController,
+ SystemWindows systemWindows, DisplayImeController imeController, @Main Handler handler,
KeyguardStateController keyguardStateController, TransactionPool transactionPool) {
- return new Divider(context, recentsOptionalLazy, displayController, systemWindows,
- imeController, handler, keyguardStateController, transactionPool);
+ // TODO(b/161116823): fetch DividerProxy from WM shell lib.
+ DividerController dividerController = new DividerController(context, displayController,
+ systemWindows, imeController, handler, transactionPool);
+ return new Divider(context, dividerController, keyguardStateController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
index 3a5c61e6d7f0..8e79d51ee209 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
@@ -21,6 +21,5 @@ package com.android.systemui.stackdivider;
*/
public class DividerState {
public boolean animateAfterRecentsDrawn;
- public boolean growAfterRecentsDrawn;
public float mRatioPositionBeforeMinimized;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index b6c6afd523b3..e5c02d6fc454 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -76,12 +76,11 @@ import java.util.function.Consumer;
public class DividerView extends FrameLayout implements OnTouchListener,
OnComputeInternalInsetsListener {
private static final String TAG = "DividerView";
- private static final boolean DEBUG = Divider.DEBUG;
+ private static final boolean DEBUG = DividerController.DEBUG;
public interface DividerCallbacks {
void onDraggingStart();
void onDraggingEnd();
- void growRecents();
}
static final long TOUCH_ANIMATION_DURATION = 150;
@@ -148,7 +147,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
private DividerCallbacks mCallback;
private final AnimationHandler mAnimationHandler = new AnimationHandler();
- private boolean mGrowRecents;
private ValueAnimator mCurrentAnimator;
private boolean mEntranceAnimationRunning;
private boolean mExitAnimationRunning;
@@ -304,7 +302,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
R.dimen.docked_stack_divider_lift_elevation);
mLongPressEntraceAnimDuration = getResources().getInteger(
R.integer.long_press_dock_anim_duration);
- mGrowRecents = getResources().getBoolean(R.bool.recents_grow_in_multiwindow);
mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
mFlingAnimationUtils = new FlingAnimationUtils(getResources().getDisplayMetrics(), 0.3f);
boolean landscape = getResources().getConfiguration().orientation
@@ -437,17 +434,17 @@ public class DividerView extends FrameLayout implements OnTouchListener,
releaseBackground();
}
- public void stopDragging(int position, SnapTarget target, long duration,
+ private void stopDragging(int position, SnapTarget target, long duration,
Interpolator interpolator) {
stopDragging(position, target, duration, 0 /* startDelay*/, 0 /* endDelay */, interpolator);
}
- public void stopDragging(int position, SnapTarget target, long duration,
+ private void stopDragging(int position, SnapTarget target, long duration,
Interpolator interpolator, long endDelay) {
stopDragging(position, target, duration, 0 /* startDelay*/, endDelay, interpolator);
}
- public void stopDragging(int position, SnapTarget target, long duration, long startDelay,
+ private void stopDragging(int position, SnapTarget target, long duration, long startDelay,
long endDelay, Interpolator interpolator) {
mHandle.setTouching(false, true /* animate */);
flingTo(position, target, duration, startDelay, endDelay, interpolator);
@@ -1319,39 +1316,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
mBackground.getRight(), mBackground.getBottom(), Op.UNION);
}
- /**
- * Checks whether recents will grow when invoked. This happens in multi-window when recents is
- * very small. When invoking recents, we shrink the docked stack so recents has more space.
- *
- * @return the position of the divider when recents grows, or
- * {@link #INVALID_RECENTS_GROW_TARGET} if recents won't grow
- */
- public int growsRecents() {
- boolean result = mGrowRecents
- && mDockSide == WindowManager.DOCKED_TOP
- && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position;
- if (result) {
- return getSnapAlgorithm().getMiddleTarget().position;
- } else {
- return INVALID_RECENTS_GROW_TARGET;
- }
- }
-
- void onRecentsActivityStarting() {
- if (mGrowRecents && mDockSide == WindowManager.DOCKED_TOP
- && getSnapAlgorithm().getMiddleTarget() != getSnapAlgorithm().getLastSplitTarget()
- && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) {
- mState.growAfterRecentsDrawn = true;
- startDragging(false /* animate */, false /* touching */);
- }
- }
-
void onDockedFirstAnimationFrame() {
saveSnapTargetBeforeMinimized(mSplitLayout.getSnapAlgorithm().getMiddleTarget());
}
void onDockedTopTask() {
- mState.growAfterRecentsDrawn = false;
mState.animateAfterRecentsDrawn = true;
startDragging(false /* animate */, false /* touching */);
updateDockSide();
@@ -1377,15 +1346,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
200 /* endDelay */);
});
}
- if (mState.growAfterRecentsDrawn) {
- mState.growAfterRecentsDrawn = false;
- updateDockSide();
- if (mCallback != null) {
- mCallback.growRecents();
- }
- stopDragging(position, getSnapAlgorithm().getMiddleTarget(), 336,
- Interpolators.FAST_OUT_SLOW_IN);
- }
}
void onUndockingTask() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index db7996eed7f0..f412cc00981b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -75,7 +75,8 @@ public class ForcedResizableInfoActivityController {
}
}
- public ForcedResizableInfoActivityController(Context context, Divider divider) {
+ public ForcedResizableInfoActivityController(Context context,
+ DividerController dividerController) {
mContext = context;
ActivityManagerWrapper.getInstance().registerTaskStackListener(
new TaskStackChangeListener() {
@@ -95,7 +96,7 @@ public class ForcedResizableInfoActivityController {
activityLaunchOnSecondaryDisplayFailed();
}
});
- divider.registerInSplitScreenListener(mDockedStackExistsListener);
+ dividerController.registerInSplitScreenListener(mDockedStackExistsListener);
}
public void onAppTransitionFinished() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index 7a313dc0622b..ef5e8a15882c 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -35,7 +35,7 @@ import android.window.TaskOrganizer;
class SplitScreenTaskOrganizer extends TaskOrganizer {
private static final String TAG = "SplitScreenTaskOrg";
- private static final boolean DEBUG = Divider.DEBUG;
+ private static final boolean DEBUG = DividerController.DEBUG;
RunningTaskInfo mPrimary;
RunningTaskInfo mSecondary;
@@ -44,13 +44,13 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
SurfaceControl mPrimaryDim;
SurfaceControl mSecondaryDim;
Rect mHomeBounds = new Rect();
- final Divider mDivider;
+ final DividerController mDividerController;
private boolean mSplitScreenSupported = false;
final SurfaceSession mSurfaceSession = new SurfaceSession();
- SplitScreenTaskOrganizer(Divider divider) {
- mDivider = divider;
+ SplitScreenTaskOrganizer(DividerController dividerController) {
+ mDividerController = dividerController;
}
void init() throws RemoteException {
@@ -75,11 +75,11 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
}
SurfaceControl.Transaction getTransaction() {
- return mDivider.mTransactionPool.acquire();
+ return mDividerController.mTransactionPool.acquire();
}
void releaseTransaction(SurfaceControl.Transaction t) {
- mDivider.mTransactionPool.release(t);
+ mDividerController.mTransactionPool.release(t);
}
@Override
@@ -140,7 +140,7 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
t.apply();
releaseTransaction(t);
- mDivider.onTaskVanished();
+ mDividerController.onTaskVanished();
}
}
}
@@ -150,7 +150,7 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
if (taskInfo.displayId != DEFAULT_DISPLAY) {
return;
}
- mDivider.getHandler().post(() -> handleTaskInfoChanged(taskInfo));
+ mDividerController.post(() -> handleTaskInfoChanged(taskInfo));
}
/**
@@ -169,7 +169,7 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
}
final boolean secondaryImpliedMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
|| (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
- && mDivider.isHomeStackResizable());
+ && mDividerController.isHomeStackResizable());
final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
final boolean secondaryWasEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
if (info.token.asBinder() == mPrimary.token.asBinder()) {
@@ -181,7 +181,7 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
final boolean secondaryIsEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
final boolean secondaryImpliesMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
|| (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
- && mDivider.isHomeStackResizable());
+ && mDividerController.isHomeStackResizable());
if (DEBUG) {
Log.d(TAG, "onTaskInfoChanged " + mPrimary + " " + mSecondary);
}
@@ -197,14 +197,14 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
Log.d(TAG, " at-least one split empty " + mPrimary.topActivityType
+ " " + mSecondary.topActivityType);
}
- if (mDivider.isDividerVisible()) {
+ if (mDividerController.isDividerVisible()) {
// Was in split-mode, which means we are leaving split, so continue that.
// This happens when the stack in the primary-split is dismissed.
if (DEBUG) {
Log.d(TAG, " was in split, so this means leave it "
+ mPrimary.topActivityType + " " + mSecondary.topActivityType);
}
- mDivider.startDismissSplit();
+ mDividerController.startDismissSplit();
} else if (!primaryIsEmpty && primaryWasEmpty && secondaryWasEmpty) {
// Wasn't in split-mode (both were empty), but now that the primary split is
// populated, we should fully enter split by moving everything else into secondary.
@@ -213,15 +213,15 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
if (DEBUG) {
Log.d(TAG, " was not in split, but primary is populated, so enter it");
}
- mDivider.startEnterSplit();
+ mDividerController.startEnterSplit();
}
} else if (secondaryImpliesMinimize) {
// Both splits are populated but the secondary split has a home/recents stack on top,
// so enter minimized mode.
- mDivider.ensureMinimizedSplit();
+ mDividerController.ensureMinimizedSplit();
} else {
// Both splits are populated by normal activities, so make sure we aren't minimized.
- mDivider.ensureNormalSplit();
+ mDividerController.ensureNormalSplit();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
index 6812f62422a7..f2500e59abab 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
@@ -33,7 +33,7 @@ import java.util.ArrayList;
* Helper for serializing sync-transactions and corresponding callbacks.
*/
class SyncTransactionQueue {
- private static final boolean DEBUG = Divider.DEBUG;
+ private static final boolean DEBUG = DividerController.DEBUG;
private static final String TAG = "SyncTransactionQueue";
// Just a little longer than the sync-engine timeout of 5s
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 2b3681281064..82b10bd40b17 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -50,7 +50,7 @@ import java.util.concurrent.Executors;
/**
* Proxy to simplify calls into window manager/activity manager
*/
-public class WindowManagerProxy {
+class WindowManagerProxy {
private static final String TAG = "WindowManagerProxy";
private static final int[] HOME_AND_RECENTS = {ACTIVITY_TYPE_HOME, ACTIVITY_TYPE_RECENTS};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java
index ca0f62ea7538..b813b6280c12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java
@@ -20,9 +20,16 @@ import static android.service.notification.NotificationListenerService.Ranking;
import android.content.ContentResolver;
import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import javax.inject.Inject;
@@ -35,23 +42,42 @@ import javax.inject.Singleton;
* should show an indicator.
*/
@Singleton
-public class AssistantFeedbackController {
+public class AssistantFeedbackController extends ContentObserver {
+ private final Uri FEEDBACK_URI
+ = Settings.Global.getUriFor(Settings.Global.NOTIFICATION_FEEDBACK_ENABLED);
private ContentResolver mResolver;
+ private boolean mFeedbackEnabled;
+
/** Injected constructor */
@Inject
public AssistantFeedbackController(Context context) {
+ super(new Handler(Looper.getMainLooper()));
mResolver = context.getContentResolver();
+ mResolver.registerContentObserver(FEEDBACK_URI, false, this, UserHandle.USER_ALL);
+ update(null);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, @Nullable Uri uri, int flags) {
+ update(uri);
+ }
+
+ @VisibleForTesting
+ public void update(@Nullable Uri uri) {
+ if (uri == null || FEEDBACK_URI.equals(uri)) {
+ mFeedbackEnabled = Settings.Global.getInt(mResolver,
+ Settings.Global.NOTIFICATION_FEEDBACK_ENABLED, 0)
+ != 0;
+ }
}
/**
* Determines whether to show any user controls related to the assistant. This is based on the
- * settings flag {@link Settings.Secure.NOTIFICATION_FEEDBACK_ENABLED}
+ * settings flag {@link Settings.Global.NOTIFICATION_FEEDBACK_ENABLED}
*/
public boolean isFeedbackEnabled() {
- return Settings.Secure.getIntForUser(mResolver,
- Settings.Secure.NOTIFICATION_FEEDBACK_ENABLED, 0,
- UserHandle.USER_CURRENT) == 1;
+ return mFeedbackEnabled;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index aba9e1005559..e1ff872456eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -15,7 +15,6 @@
*/
package com.android.systemui.statusbar.notification;
-import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_ERROR;
import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_UNKNOWN;
@@ -24,14 +23,11 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
-import android.content.Context;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.NotificationStats;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -41,7 +37,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationListener;
@@ -54,11 +49,11 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
+import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.Assert;
import com.android.systemui.util.leak.LeakDetector;
@@ -147,8 +142,6 @@ public class NotificationEntryManager implements
private final NotificationRankingManager mRankingManager;
private final FeatureFlags mFeatureFlags;
private final ForegroundServiceDismissalFeatureController mFgsFeatureController;
- private final HeadsUpManager mHeadsUpManager;
- private final StatusBarStateController mStatusBarStateController;
private NotificationPresenter mPresenter;
private RankingMap mLatestRankingMap;
@@ -213,8 +206,7 @@ public class NotificationEntryManager implements
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
LeakDetector leakDetector,
ForegroundServiceDismissalFeatureController fgsFeatureController,
- HeadsUpManager headsUpManager,
- StatusBarStateController statusBarStateController
+ IStatusBarService statusBarService
) {
mLogger = logger;
mGroupManager = groupManager;
@@ -225,11 +217,7 @@ public class NotificationEntryManager implements
mRemoteInputManagerLazy = notificationRemoteInputManagerLazy;
mLeakDetector = leakDetector;
mFgsFeatureController = fgsFeatureController;
- mHeadsUpManager = headsUpManager;
- mStatusBarStateController = statusBarStateController;
-
- mStatusBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
+ mStatusBarService = statusBarService;
}
/** Once called, the NEM will start processing notification events from system server. */
@@ -284,16 +272,23 @@ public class NotificationEntryManager implements
}
/**
- * Requests a notification to be removed.
+ * User requests a notification to be removed.
*
* @param n the notification to remove.
* @param reason why it is being removed e.g. {@link NotificationListenerService#REASON_CANCEL},
* or 0 if unknown.
*/
- public void performRemoveNotification(StatusBarNotification n, int reason) {
- final NotificationVisibility nv = obtainVisibility(n.getKey());
+ public void performRemoveNotification(
+ StatusBarNotification n,
+ @NonNull DismissedByUserStats stats,
+ int reason
+ ) {
removeNotificationInternal(
- n.getKey(), null, nv, false /* forceRemove */, true /* removedByUser */,
+ n.getKey(),
+ null,
+ stats.notificationVisibility,
+ false /* forceRemove */,
+ stats,
reason);
}
@@ -337,7 +332,11 @@ public class NotificationEntryManager implements
*/
private void handleInflationException(StatusBarNotification n, Exception e) {
removeNotificationInternal(
- n.getKey(), null, null, true /* forceRemove */, false /* removedByUser */,
+ n.getKey(),
+ null,
+ null,
+ true /* forceRemove */,
+ null /* dismissedByUserStats */,
REASON_ERROR);
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onInflationError(n, e);
@@ -435,19 +434,28 @@ public class NotificationEntryManager implements
reapplyFilterAndSort("addVisibleNotification");
}
-
- public void removeNotification(String key, RankingMap ranking,
- int reason) {
- removeNotificationInternal(key, ranking, obtainVisibility(key), false /* forceRemove */,
- false /* removedByUser */, reason);
+ @VisibleForTesting
+ protected void removeNotification(String key, RankingMap ranking, int reason) {
+ removeNotificationInternal(
+ key,
+ ranking,
+ obtainVisibility(key),
+ false /* forceRemove */,
+ null /* dismissedByUserStats */,
+ reason);
}
+ /**
+ * Internally remove a notification because system server has reported the notification
+ * should be removed OR the user has manually dismissed the notification
+ * @param dismissedByUserStats non-null if the user manually dismissed the notification
+ */
private void removeNotificationInternal(
String key,
@Nullable RankingMap ranking,
@Nullable NotificationVisibility visibility,
boolean forceRemove,
- boolean removedByUser,
+ DismissedByUserStats dismissedByUserStats,
int reason) {
final NotificationEntry entry = getActiveNotificationUnfiltered(key);
@@ -512,11 +520,11 @@ public class NotificationEntryManager implements
handleGroupSummaryRemoved(key);
removeVisibleNotification(key);
updateNotifications("removeNotificationInternal");
- removedByUser |= entryDismissed;
+ final boolean removedByUser = dismissedByUserStats != null;
mLogger.logNotifRemoved(entry.getKey(), removedByUser);
if (removedByUser && visibility != null) {
- sendNotificationRemovalToServer(entry.getKey(), entry.getSbn(), visibility);
+ sendNotificationRemovalToServer(entry.getSbn(), dismissedByUserStats);
}
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onEntryRemoved(entry, visibility, removedByUser, reason);
@@ -534,30 +542,18 @@ public class NotificationEntryManager implements
}
private void sendNotificationRemovalToServer(
- String key,
StatusBarNotification notification,
- NotificationVisibility nv) {
- final String pkg = notification.getPackageName();
- final String tag = notification.getTag();
- final int id = notification.getId();
- final int userId = notification.getUser().getIdentifier();
+ DismissedByUserStats dismissedByUserStats) {
try {
- int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
- if (mHeadsUpManager.isAlerting(key)) {
- dismissalSurface = NotificationStats.DISMISSAL_PEEK;
- } else if (mStatusBarStateController.isDozing()) {
- dismissalSurface = NotificationStats.DISMISSAL_AOD;
- }
- int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
mStatusBarService.onNotificationClear(
- pkg,
- tag,
- id,
- userId,
+ notification.getPackageName(),
+ notification.getTag(),
+ notification.getId(),
+ notification.getUser().getIdentifier(),
notification.getKey(),
- dismissalSurface,
- dismissalSentiment,
- nv);
+ dismissedByUserStats.dismissalSurface,
+ dismissedByUserStats.dismissalSentiment,
+ dismissedByUserStats.notificationVisibility);
} catch (RemoteException ex) {
// system process is dead if we're here.
}
@@ -641,11 +637,7 @@ public class NotificationEntryManager implements
// Construct the expanded view.
if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- mNotificationRowBinderLazy.get()
- .inflateViews(
- entry,
- () -> performRemoveNotification(notification, REASON_CANCEL),
- mInflationCallback);
+ mNotificationRowBinderLazy.get().inflateViews(entry, mInflationCallback);
}
mPendingNotifications.put(key, entry);
@@ -675,7 +667,7 @@ public class NotificationEntryManager implements
final String key = notification.getKey();
abortExistingInflation(key, "updateNotification");
- NotificationEntry entry = getActiveNotificationUnfiltered(key);
+ final NotificationEntry entry = getActiveNotificationUnfiltered(key);
if (entry == null) {
return;
}
@@ -701,11 +693,7 @@ public class NotificationEntryManager implements
}
if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- mNotificationRowBinderLazy.get()
- .inflateViews(
- entry,
- () -> performRemoveNotification(notification, REASON_CANCEL),
- mInflationCallback);
+ mNotificationRowBinderLazy.get().inflateViews(entry, mInflationCallback);
}
updateNotifications("updateNotificationInternal");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
index 97c1523887ad..3a0520115d67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.notification.collection;
import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_NOT_CANCELED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.NOT_DISMISSED;
+import static java.util.Objects.requireNonNull;
+
import com.android.systemui.statusbar.NotificationInteractionTracker;
import java.util.Arrays;
@@ -56,7 +58,7 @@ public class ListDumper {
List<NotificationEntry> children = ge.getChildren();
for (int childIndex = 0; childIndex < children.size(); childIndex++) {
dumpEntry(children.get(childIndex),
- Integer.toString(topEntryIndex) + "." + Integer.toString(childIndex),
+ topEntryIndex + "." + childIndex,
childEntryIndent,
sb,
true,
@@ -118,7 +120,7 @@ public class ListDumper {
}
if (includeRecordKeeping) {
- NotificationEntry notifEntry = entry.getRepresentativeEntry();
+ NotificationEntry notifEntry = requireNonNull(entry.getRepresentativeEntry());
StringBuilder rksb = new StringBuilder();
if (!notifEntry.mLifetimeExtenders.isEmpty()) {
@@ -165,7 +167,9 @@ public class ListDumper {
.append(" ");
}
- rksb.append("interacted=").append(hasBeenInteractedWith ? "yes" : "no").append(" ");
+ if (hasBeenInteractedWith) {
+ rksb.append("interacted=yes ");
+ }
String rkString = rksb.toString();
if (!rkString.isEmpty()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
index d081e114855e..aaf5c4d6594b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
@@ -16,17 +16,10 @@
package com.android.systemui.statusbar.notification.collection;
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-
-import android.service.notification.NotificationStats;
-
import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater;
@@ -81,7 +74,6 @@ public class NotifInflaterImpl implements NotifInflater {
try {
requireBinder().inflateViews(
entry,
- getDismissCallback(entry),
wrapInflationCallback(callback));
} catch (InflationException e) {
mNotifErrorManager.setInflationError(entry, e);
@@ -93,30 +85,6 @@ public class NotifInflaterImpl implements NotifInflater {
entry.abortTask();
}
- private Runnable getDismissCallback(NotificationEntry entry) {
- return new Runnable() {
- @Override
- public void run() {
- int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
- /*
- * TODO: determine dismissal surface (ie: shade / headsup / aod)
- * see {@link NotificationLogger#logNotificationClear}
- */
- mNotifCollection.dismissNotification(
- entry,
- new DismissedByUserStats(
- dismissalSurface,
- DISMISS_SENTIMENT_NEUTRAL,
- NotificationVisibility.obtain(entry.getKey(),
- entry.getRanking().getRank(),
- mNotifPipeline.getShadeListCount(),
- true,
- NotificationLogger.getNotificationLocation(entry))
- ));
- }
- };
- }
-
private NotificationContentInflater.InflationCallback wrapInflationCallback(
InflationCallback callback) {
return new NotificationContentInflater.InflationCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt
deleted file mode 100644
index 339809e0770b..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt
+++ /dev/null
@@ -1,204 +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.
- */
-
-package com.android.systemui.statusbar.notification.collection
-
-import android.annotation.MainThread
-import android.view.ViewGroup
-
-import com.android.systemui.statusbar.FeatureFlags
-import com.android.systemui.statusbar.notification.VisualStabilityManager
-import com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY
-import com.android.systemui.statusbar.notification.stack.NotificationListItem
-import com.android.systemui.util.Assert
-
-import java.io.FileDescriptor
-import java.io.PrintWriter
-import java.lang.IllegalStateException
-import javax.inject.Inject
-import javax.inject.Singleton
-
-/**
- * A consumer of a Notification tree built by [ShadeListBuilder] which will update the notification
- * presenter with the minimum operations required to make the old tree match the new one
- */
-@MainThread
-@Singleton
-class NotifViewManager @Inject constructor(
- private val rowRegistry: NotifViewBarn,
- private val stabilityManager: VisualStabilityManager,
- private val featureFlags: FeatureFlags
-) {
- var currentNotifs = listOf<ListEntry>()
-
- private lateinit var listContainer: SimpleNotificationListContainer
-
- fun attach(listBuilder: ShadeListBuilder) {
- if (featureFlags.isNewNotifPipelineRenderingEnabled) {
- listBuilder.setOnRenderListListener { entries: List<ListEntry> ->
- this.onNotifTreeBuilt(entries)
- }
- }
- }
-
- fun setViewConsumer(consumer: SimpleNotificationListContainer) {
- listContainer = consumer
- }
-
- /**
- * Callback for when the tree is rebuilt
- */
- fun onNotifTreeBuilt(notifList: List<ListEntry>) {
- Assert.isMainThread()
-
- /*
- * The assumption here is that anything from the old NotificationViewHierarchyManager that
- * is responsible for filtering is done via the NotifFilter logic. This tree we get should
- * be *the stuff to display* +/- redacted stuff
- */
-
- detachRows(notifList)
- attachRows(notifList)
-
- currentNotifs = notifList
- }
-
- private fun detachRows(entries: List<ListEntry>) {
- // To properly detach rows, we are looking to remove any view in the consumer that is not
- // present in the incoming list.
- //
- // Every listItem was top-level, so it's entry's parent was ROOT_ENTRY, but now
- // there are two possibilities:
- //
- // 1. It is not present in the entry list
- // 1a. It has moved to be a child in the entry list - transfer it
- // 1b. It is gone completely - remove it
- // 2. It is present in the entry list - diff the children
- getListItems(listContainer)
- .filter {
- // Ignore things that are showing the blocking helper
- !it.isBlockingHelperShowing
- }
- .forEach { listItem ->
- val noLongerTopLevel = listItem.entry.parent != ROOT_ENTRY
- val becameChild = noLongerTopLevel && listItem.entry.parent != null
-
- val idx = entries.indexOf(listItem.entry)
-
- if (noLongerTopLevel) {
- // Summaries won't become children; remove the whole group
- if (listItem.isSummaryWithChildren) {
- listItem.removeAllChildren()
- }
-
- if (becameChild) {
- // Top-level element is becoming a child, don't generate an animation
- listContainer.setChildTransferInProgress(true)
- }
- listContainer.removeListItem(listItem)
- listContainer.setChildTransferInProgress(false)
- } else if (entries[idx] is GroupEntry) {
- // A top-level entry exists. If it's a group, diff the children
- val groupChildren = (entries[idx] as GroupEntry).children
- listItem.attachedChildren?.forEach { listChild ->
- if (!groupChildren.contains(listChild.entry)) {
- listItem.removeChildNotification(listChild)
-
- // TODO: the old code only calls this if the notif is gone from
- // NEM.getActiveNotificationUnfiltered(). Do we care?
- listContainer.notifyGroupChildRemoved(
- listChild.view, listChild.view.parent as ViewGroup)
- }
- }
- }
- }
- }
-
- /** Convenience method for getting a sequence of [NotificationListItem]s */
- private fun getListItems(container: SimpleNotificationListContainer):
- Sequence<NotificationListItem> {
- return (0 until container.getContainerChildCount()).asSequence()
- .map { container.getContainerChildAt(it) }
- .filterIsInstance<NotificationListItem>()
- }
-
- private fun attachRows(entries: List<ListEntry>) {
-
- var orderChanged = false
-
- // To attach rows we can use _this one weird trick_: if the intended view to add does not
- // have a parent, then simply add it (and its children).
- entries.forEach { entry ->
- // TODO: We should eventually map GroupEntry's themselves to views so that we don't
- // depend on representativeEntry here which may actually be null in the future
- val listItem = rowRegistry.requireView(entry.representativeEntry!!)
-
- if (listItem.view.parent == null) {
- listContainer.addListItem(listItem)
- stabilityManager.notifyViewAddition(listItem.view)
- }
-
- if (entry is GroupEntry) {
- for ((idx, childEntry) in entry.children.withIndex()) {
- val childListItem = rowRegistry.requireView(childEntry)
- // Child hasn't been added yet. add it!
- if (listItem.attachedChildren == null ||
- !listItem.attachedChildren.contains(childListItem)) {
- // TODO: old code here just Log.wtf()'d here. This might wreak havoc
- if (childListItem.view.parent != null) {
- throw IllegalStateException("trying to add a notification child that " +
- "already has a parent. class: " +
- "${childListItem.view.parent?.javaClass} " +
- "\n child: ${childListItem.view}"
- )
- }
-
- listItem.addChildNotification(childListItem, idx)
- stabilityManager.notifyViewAddition(childListItem.view)
- listContainer.notifyGroupChildAdded(childListItem.view)
- }
- }
-
- // finally after removing and adding has been performed we can apply the order
- orderChanged = orderChanged ||
- listItem.applyChildOrder(
- getChildListFromParent(entry),
- stabilityManager,
- null /*TODO: stability callback */
- )
- listItem.setUntruncatedChildCount(entry.untruncatedChildCount)
- }
- }
-
- if (orderChanged) {
- listContainer.generateChildOrderChangedEvent()
- }
- }
-
- private fun getChildListFromParent(parent: ListEntry): List<NotificationListItem> {
- if (parent is GroupEntry) {
- return parent.children.map { child -> rowRegistry.requireView(child) }
- .toList()
- }
-
- return emptyList()
- }
-
- fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
- }
-}
-
-private const val TAG = "NotifViewDataSource" \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 6f78411dc10e..d45f89cb6fe5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -865,7 +865,7 @@ public class ShadeListBuilder implements Dumpable {
}
};
- private static final String TAG = "NotifListBuilderImpl";
+ private static final String TAG = "ShadeListBuilder";
private static final int MIN_CHILDREN_FOR_GROUP = 2;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt
deleted file mode 100644
index 2dbe555af519..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt
+++ /dev/null
@@ -1,43 +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.
- */
-
-package com.android.systemui.statusbar.notification.collection
-
-import android.view.View
-import android.view.ViewGroup
-import com.android.systemui.statusbar.notification.stack.NotificationListItem
-
-/**
- * Minimal interface of what [NotifViewManager] needs from [NotificationListContainer]
- */
-interface SimpleNotificationListContainer {
- /** Called to signify that a top-level element is becoming a child in the shade */
- fun setChildTransferInProgress(b: Boolean)
- /** Used to generate a list of [NotificationListItem] */
- fun getContainerChildAt(i: Int): View
- /** Similar to above */
- fun getContainerChildCount(): Int
- /** Remove a [NotificationListItem] from the container */
- fun removeListItem(li: NotificationListItem)
- /** Add a [NotificationListItem] to the container */
- fun addListItem(li: NotificationListItem)
- /** Allows [NotifViewManager] to notify the container about a group child removal */
- fun notifyGroupChildRemoved(row: View, parent: ViewGroup)
- /** Allows [NotifViewManager] to notify the container about a group child addition */
- fun notifyGroupChildAdded(row: View)
- /** [NotifViewManager] calls this when the order of the children changes */
- fun generateChildOrderChangedEvent()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
index 92426e54ec91..08462c183bd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
@@ -16,10 +16,6 @@
package com.android.systemui.statusbar.notification.collection.coordinator;
-import static android.service.notification.NotificationStats.DISMISSAL_OTHER;
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-
-import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -27,7 +23,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import java.util.HashSet;
import java.util.Set;
@@ -101,7 +96,6 @@ public class BubbleCoordinator implements Coordinator {
@Override
public boolean shouldInterceptDismissal(NotificationEntry entry) {
- // TODO: b/149041810 add support for intercepting app-cancelled bubble notifications
// for experimental bubbles
if (mBubbleController.handleDismissalInterception(entry)) {
mInterceptedDismissalEntries.add(entry.getKey());
@@ -121,17 +115,21 @@ public class BubbleCoordinator implements Coordinator {
private final BubbleController.NotifCallback mNotifCallback =
new BubbleController.NotifCallback() {
@Override
- public void removeNotification(NotificationEntry entry, int reason) {
+ public void removeNotification(
+ NotificationEntry entry,
+ DismissedByUserStats dismissedByUserStats,
+ int reason
+ ) {
if (isInterceptingDismissal(entry)) {
mInterceptedDismissalEntries.remove(entry.getKey());
mOnEndDismissInterception.onEndDismissInterception(mDismissInterceptor, entry,
- createDismissedByUserStats(entry));
+ dismissedByUserStats);
} else if (mNotifPipeline.getAllNotifs().contains(entry)) {
// Bubbles are hiding the notifications from the shade, but the bubble was
// deleted; therefore, the notification should be cancelled as if it were a user
// dismissal (this won't re-enter handleInterceptDimissal because Bubbles
// will have already marked it as no longer a bubble)
- mNotifCollection.dismissNotification(entry, createDismissedByUserStats(entry));
+ mNotifCollection.dismissNotification(entry, dismissedByUserStats);
}
}
@@ -149,16 +147,4 @@ public class BubbleCoordinator implements Coordinator {
private boolean isInterceptingDismissal(NotificationEntry entry) {
return mInterceptedDismissalEntries.contains(entry.getKey());
}
-
- private DismissedByUserStats createDismissedByUserStats(NotificationEntry entry) {
- return new DismissedByUserStats(
- DISMISSAL_OTHER,
- DISMISS_SENTIMENT_NEUTRAL,
- NotificationVisibility.obtain(entry.getKey(),
- entry.getRanking().getRank(),
- mNotifPipeline.getShadeListCount(),
- true, // was visible as a bubble
- NotificationLogger.getNotificationLocation(entry))
- );
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index b7738569ad3c..95ba759df547 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -64,6 +64,8 @@ public class KeyguardCoordinator implements Coordinator {
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final HighPriorityProvider mHighPriorityProvider;
+ private boolean mHideSilentNotificationsOnLockscreen;
+
@Inject
public KeyguardCoordinator(
Context context,
@@ -86,6 +88,8 @@ public class KeyguardCoordinator implements Coordinator {
@Override
public void attach(NotifPipeline pipeline) {
+ readShowSilentNotificationSetting();
+
setupInvalidateNotifListCallbacks();
pipeline.addFinalizeFilter(mNotifFilter);
}
@@ -147,7 +151,7 @@ public class KeyguardCoordinator implements Coordinator {
return false;
}
if (NotificationUtils.useNewInterruptionModel(mContext)
- && hideSilentNotificationsOnLockscreen()) {
+ && mHideSilentNotificationsOnLockscreen) {
return mHighPriorityProvider.isHighPriority(entry);
} else {
return entry.getRepresentativeEntry() != null
@@ -155,11 +159,6 @@ public class KeyguardCoordinator implements Coordinator {
}
}
- private boolean hideSilentNotificationsOnLockscreen() {
- return Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
- }
-
private void setupInvalidateNotifListCallbacks() {
// register onKeyguardShowing callback
mKeyguardStateController.addCallback(mKeyguardCallback);
@@ -169,6 +168,11 @@ public class KeyguardCoordinator implements Coordinator {
final ContentObserver settingsObserver = new ContentObserver(mMainHandler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
+ if (uri.equals(Settings.Secure.getUriFor(
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS))) {
+ readShowSilentNotificationSetting();
+ }
+
if (mKeyguardStateController.isShowing()) {
invalidateListFromFilter("Settings " + uri + " changed");
}
@@ -192,6 +196,12 @@ public class KeyguardCoordinator implements Coordinator {
false,
settingsObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
+ false,
+ settingsObserver,
+ UserHandle.USER_ALL);
+
// register (maybe) public mode changed callbacks:
mStatusBarStateController.addCallback(mStatusBarStateListener);
mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
@@ -208,6 +218,14 @@ public class KeyguardCoordinator implements Coordinator {
mNotifFilter.invalidateList();
}
+ private void readShowSilentNotificationSetting() {
+ mHideSilentNotificationsOnLockscreen =
+ Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
+ 1) == 0;
+ }
+
private final KeyguardStateController.Callback mKeyguardCallback =
new KeyguardStateController.Callback() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index 9baadddc55db..ee2bb6b1d190 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -31,13 +31,13 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotifViewBarn;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager.NotifInflationErrorListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
index 710b137d2795..1215ade2abb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
@@ -38,7 +38,6 @@ public interface NotificationRowBinder {
*/
void inflateViews(
NotificationEntry entry,
- Runnable onDismissRunnable,
NotificationRowContentBinder.InflationCallback callback)
throws InflationException;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 85a3bc91dc7e..8849824380d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -32,7 +32,6 @@ import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.icon.IconManager;
-import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
@@ -59,7 +58,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
private final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
private final NotifBindPipeline mNotifBindPipeline;
private final RowContentBindStage mRowContentBindStage;
- private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final Provider<RowInflaterTask> mRowInflaterTaskProvider;
private final ExpandableNotificationRowComponent.Builder
mExpandableNotificationRowComponentBuilder;
@@ -79,7 +77,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotifBindPipeline notifBindPipeline,
RowContentBindStage rowContentBindStage,
- NotificationInterruptStateProvider notificationInterruptionStateProvider,
Provider<RowInflaterTask> rowInflaterTaskProvider,
ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder,
IconManager iconManager,
@@ -90,7 +87,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
mMessagingUtil = notificationMessagingUtil;
mNotificationRemoteInputManager = notificationRemoteInputManager;
mNotificationLockscreenUserManager = notificationLockscreenUserManager;
- mNotificationInterruptStateProvider = notificationInterruptionStateProvider;
mRowInflaterTaskProvider = rowInflaterTaskProvider;
mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
mIconManager = iconManager;
@@ -120,7 +116,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
@Override
public void inflateViews(
NotificationEntry entry,
- Runnable onDismissRunnable,
NotificationRowContentBinder.InflationCallback callback)
throws InflationException {
ViewGroup parent = mListContainer.getViewParentForNotification(entry);
@@ -131,7 +126,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
row.reset();
updateRow(entry, row);
inflateContentViews(entry, row, callback);
- entry.getRowController().setOnDismissRunnable(onDismissRunnable);
} else {
mIconManager.createIcons(entry);
mRowInflaterTaskProvider.get().inflate(mContext, parent, entry,
@@ -141,7 +135,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
mExpandableNotificationRowComponentBuilder
.expandableNotificationRow(row)
.notificationEntry(entry)
- .onDismissRunnable(onDismissRunnable)
.onExpandClickListener(mPresenter)
.build();
ExpandableNotificationRowController rowController =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java
new file mode 100644
index 000000000000..36adf9b87674
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java
@@ -0,0 +1,83 @@
+/*
+ * 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.systemui.statusbar.notification.collection.inflation;
+
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
+
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationStats;
+
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.collection.NotifCollection;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+
+/**
+ * Callback used when a user:
+ * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
+ * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
+ * {@see StatusBarNotificationActivityStarter}
+ */
+public class OnDismissCallbackImpl implements OnDismissCallback {
+ private final NotifPipeline mNotifPipeline;
+ private final NotifCollection mNotifCollection;
+ private final HeadsUpManager mHeadsUpManager;
+ private final StatusBarStateController mStatusBarStateController;
+
+ public OnDismissCallbackImpl(
+ NotifPipeline notifPipeline,
+ NotifCollection notifCollection,
+ HeadsUpManager headsUpManager,
+ StatusBarStateController statusBarStateController
+ ) {
+ mNotifPipeline = notifPipeline;
+ mNotifCollection = notifCollection;
+ mHeadsUpManager = headsUpManager;
+ mStatusBarStateController = statusBarStateController;
+ }
+
+ @Override
+ public void onDismiss(
+ NotificationEntry entry,
+ @NotificationListenerService.NotificationCancelReason int cancellationReason
+ ) {
+ int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
+ if (mHeadsUpManager.isAlerting(entry.getKey())) {
+ dismissalSurface = NotificationStats.DISMISSAL_PEEK;
+ } else if (mStatusBarStateController.isDozing()) {
+ dismissalSurface = NotificationStats.DISMISSAL_AOD;
+ }
+
+ mNotifCollection.dismissNotification(
+ entry,
+ new DismissedByUserStats(
+ dismissalSurface,
+ DISMISS_SENTIMENT_NEUTRAL,
+ NotificationVisibility.obtain(
+ entry.getKey(),
+ entry.getRanking().getRank(),
+ mNotifPipeline.getShadeListCount(),
+ true,
+ NotificationLogger.getNotificationLocation(entry)))
+ );
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
index f150257df252..9782c3ef55fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
@@ -25,11 +25,12 @@ import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotifViewManager;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer;
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.collection.render.NotifViewManager;
+import com.android.systemui.statusbar.notification.collection.render.NotifViewManagerBuilder;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import java.io.FileDescriptor;
@@ -50,9 +51,9 @@ public class NotifPipelineInitializer implements Dumpable {
private final NotifCoordinators mNotifPluggableCoordinators;
private final NotifInflaterImpl mNotifInflater;
private final DumpManager mDumpManager;
+ private final NotifViewManagerBuilder mNotifViewManagerBuilder;
private final FeatureFlags mFeatureFlags;
- private final NotifViewManager mNotifViewManager;
@Inject
public NotifPipelineInitializer(
@@ -63,8 +64,8 @@ public class NotifPipelineInitializer implements Dumpable {
NotifCoordinators notifCoordinators,
NotifInflaterImpl notifInflater,
DumpManager dumpManager,
- FeatureFlags featureFlags,
- NotifViewManager notifViewManager) {
+ NotifViewManagerBuilder notifViewManagerBuilder,
+ FeatureFlags featureFlags) {
mPipelineWrapper = pipelineWrapper;
mGroupCoalescer = groupCoalescer;
mNotifCollection = notifCollection;
@@ -73,7 +74,7 @@ public class NotifPipelineInitializer implements Dumpable {
mDumpManager = dumpManager;
mNotifInflater = notifInflater;
mFeatureFlags = featureFlags;
- mNotifViewManager = notifViewManager;
+ mNotifViewManagerBuilder = notifViewManagerBuilder;
}
/** Hooks the new pipeline up to NotificationManager */
@@ -93,8 +94,10 @@ public class NotifPipelineInitializer implements Dumpable {
mNotifPluggableCoordinators.attach(mPipelineWrapper);
// Wire up pipeline
- mNotifViewManager.setViewConsumer(listContainer);
- mNotifViewManager.attach(mListBuilder);
+ if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
+ NotifViewManager notifViewManager = mNotifViewManagerBuilder.build(listContainer);
+ notifViewManager.attach(mListBuilder);
+ }
mListBuilder.attach(mNotifCollection);
mNotifCollection.attach(mGroupCoalescer);
mGroupCoalescer.attach(notificationService);
@@ -104,7 +107,6 @@ public class NotifPipelineInitializer implements Dumpable {
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mNotifViewManager.dump(fd, pw, args);
mNotifPluggableCoordinators.dump(fd, pw, args);
mGroupCoalescer.dump(fd, pw, args);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java
new file mode 100644
index 000000000000..94ffa8f8c5ed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java
@@ -0,0 +1,81 @@
+/*
+ * 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.systemui.statusbar.notification.collection.legacy;
+
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
+
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationStats;
+
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+
+/**
+ * Callback used when a user:
+ * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
+ * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
+ * {@see StatusBarNotificationActivityStarter}
+ */
+public class OnDismissCallbackImpl implements OnDismissCallback {
+ private final NotificationEntryManager mNotificationEntryManager;
+ private final HeadsUpManager mHeadsUpManager;
+ private final StatusBarStateController mStatusBarStateController;
+
+ public OnDismissCallbackImpl(
+ NotificationEntryManager notificationEntryManager,
+ HeadsUpManager headsUpManager,
+ StatusBarStateController statusBarStateController
+ ) {
+ mNotificationEntryManager = notificationEntryManager;
+ mHeadsUpManager = headsUpManager;
+ mStatusBarStateController = statusBarStateController;
+ }
+
+ @Override
+ public void onDismiss(
+ NotificationEntry entry,
+ @NotificationListenerService.NotificationCancelReason int cancellationReason
+ ) {
+ int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
+ if (mHeadsUpManager.isAlerting(entry.getKey())) {
+ dismissalSurface = NotificationStats.DISMISSAL_PEEK;
+ } else if (mStatusBarStateController.isDozing()) {
+ dismissalSurface = NotificationStats.DISMISSAL_AOD;
+ }
+
+ mNotificationEntryManager.performRemoveNotification(
+ entry.getSbn(),
+ new DismissedByUserStats(
+ dismissalSurface,
+ DISMISS_SENTIMENT_NEUTRAL,
+ NotificationVisibility.obtain(
+ entry.getKey(),
+ entry.getRanking().getRank(),
+ mNotificationEntryManager.getActiveNotificationsCount(),
+ true,
+ NotificationLogger.getNotificationLocation(entry))),
+ cancellationReason
+ );
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
index aa107824729e..67f8bfeaf141 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
@@ -125,13 +125,18 @@ class ShadeListBuilderLogger @Inject constructor(
str2 = prevParent?.key
str3 = newParent?.key
}, {
- if (str2 == null && str3 != null) {
- "(Build $int1) ATTACHED {$str1}"
+
+ val action = if (str2 == null && str3 != null) {
+ "ATTACHED"
} else if (str2 != null && str3 == null) {
- "(Build $int1) DETACHED {$str1}"
+ "DETACHED"
+ } else if (str2 == null && str3 == null) {
+ "MODIFIED (DETACHED)"
} else {
- "(Build $int1) MODIFIED {$str1}"
+ "MODIFIED (ATTACHED)"
}
+
+ "(Build $int1) $action {$str1}"
})
}
@@ -146,7 +151,7 @@ class ShadeListBuilderLogger @Inject constructor(
} else if (str1 != null && str2 == null) {
"(Build $int1) Parent was {$str1}"
} else {
- "(Build $int1) Reparent: {$str2} -> {$str3}"
+ "(Build $int1) Reparent: {$str1} -> {$str2}"
}
})
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
index e7948cd1216e..54000950e3ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
@@ -14,26 +14,22 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.collection
+package com.android.systemui.statusbar.notification.collection.render
import android.view.textclassifier.Log
-import com.android.systemui.statusbar.notification.stack.NotificationListItem
-import java.lang.IllegalStateException
-
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import javax.inject.Inject
import javax.inject.Singleton
/**
- * The ViewBarn is just a map from [ListEntry] to an instance of [NotificationListItem] which is
- * usually just an [ExpandableNotificationRow]
+ * The ViewBarn is just a map from [ListEntry] to an instance of an [ExpandableNotificationRow].
*/
@Singleton
class NotifViewBarn @Inject constructor() {
- private val DEBUG = false
-
- private val rowMap = mutableMapOf<String, NotificationListItem>()
+ private val rowMap = mutableMapOf<String, ExpandableNotificationRow>()
- fun requireView(forEntry: ListEntry): NotificationListItem {
+ fun requireView(forEntry: ListEntry): ExpandableNotificationRow {
if (DEBUG) {
Log.d(TAG, "requireView: $forEntry.key")
}
@@ -45,7 +41,7 @@ class NotifViewBarn @Inject constructor() {
return li
}
- fun registerViewForEntry(entry: ListEntry, view: NotificationListItem) {
+ fun registerViewForEntry(entry: ListEntry, view: ExpandableNotificationRow) {
if (DEBUG) {
Log.d(TAG, "registerViewForEntry: $entry.key")
}
@@ -60,4 +56,6 @@ class NotifViewBarn @Inject constructor() {
}
}
-private const val TAG = "NotifViewBarn" \ No newline at end of file
+private const val TAG = "NotifViewBarn"
+
+private const val DEBUG = false \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt
new file mode 100644
index 000000000000..f2e2c39ab612
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt
@@ -0,0 +1,240 @@
+/*
+ * 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.systemui.statusbar.notification.collection.render
+
+import android.annotation.MainThread
+import android.view.View
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.ShadeListBuilder
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer
+import javax.inject.Inject
+
+/**
+ * A consumer of a Notification tree built by [ShadeListBuilder] which will update the notification
+ * presenter with the minimum operations required to make the old tree match the new one
+ */
+@MainThread
+class NotifViewManager constructor(
+ private val listContainer: NotificationListContainer,
+ private val viewBarn: NotifViewBarn,
+ private val logger: NotifViewManagerLogger
+) {
+ private val rootNode = RootWrapper(listContainer)
+ private val rows = mutableMapOf<ListEntry, RowNode>()
+
+ fun attach(listBuilder: ShadeListBuilder) {
+ listBuilder.setOnRenderListListener(::onNewNotifTree)
+ }
+
+ private fun onNewNotifTree(tree: List<ListEntry>) {
+ // Step 1: Detach all views whose parents have changed
+ detachRowsWithModifiedParents()
+
+ // Step 2: Attach all new views and reattach all views whose parents changed.
+ // Also reorder existing children to match the spec we've received
+ val orderChanged = addAndReorderChildren(rootNode, tree)
+ if (orderChanged) {
+ listContainer.generateChildOrderChangedEvent()
+ }
+ }
+
+ private fun detachRowsWithModifiedParents() {
+ val toRemove = mutableListOf<ListEntry>()
+ for (row in rows.values) {
+ val oldParentEntry = row.nodeParent?.entry
+ val newParentEntry = row.entry.parent
+
+ if (newParentEntry != oldParentEntry) {
+ // If the parent is null, then we should remove the child completely. If not, then
+ // the parent merely changed: we'll detach it for now and then attach it to the
+ // new parent in step 2.
+ val isTransfer = newParentEntry != null
+ if (!isTransfer) {
+ toRemove.add(row.entry)
+ }
+
+ if (!isTransfer && !isAttachedToRootEntry(oldParentEntry)) {
+ // If our view parent has also been removed (i.e. is no longer attached to the
+ // root entry) then we skip removing the child here
+ logger.logSkippingDetach(row.entry.key, row.nodeParent?.entry?.key)
+ } else {
+ logger.logDetachingChild(
+ row.entry.key,
+ isTransfer,
+ oldParentEntry?.key,
+ newParentEntry?.key)
+ row.nodeParent?.removeChild(row, isTransfer)
+ row.nodeParent = null
+ }
+ }
+ }
+ rows.keys.removeAll(toRemove)
+ }
+
+ private fun addAndReorderChildren(parent: ParentNode, childEntries: List<ListEntry>): Boolean {
+ var orderChanged = false
+ for ((index, entry) in childEntries.withIndex()) {
+ val row = getRowNode(entry)
+ val currView = parent.getChildViewAt(index)
+ if (currView != row.view) {
+ when (row.nodeParent) {
+ null -> {
+ logger.logAttachingChild(row.entry.key, parent.entry.key)
+ parent.addChildAt(row, index)
+ row.nodeParent = parent
+ }
+ parent -> {
+ logger.logMovingChild(row.entry.key, parent.entry.key, index)
+ parent.moveChild(row, index)
+ orderChanged = true
+ }
+ else -> {
+ throw IllegalStateException("Child ${row.entry.key} should have parent " +
+ "${parent.entry.key} but is actually " +
+ "${row.nodeParent?.entry?.key}")
+ }
+ }
+ }
+ if (row is GroupWrapper) {
+ val childOrderChanged = addAndReorderChildren(row, row.entry.children)
+ orderChanged = orderChanged || childOrderChanged
+ }
+ }
+ // TODO: setUntruncatedChildCount
+
+ return orderChanged
+ }
+
+ private fun getRowNode(entry: ListEntry): RowNode {
+ return rows.getOrPut(entry) {
+ when (entry) {
+ is NotificationEntry -> RowWrapper(entry, viewBarn.requireView(entry))
+ is GroupEntry ->
+ GroupWrapper(
+ entry,
+ viewBarn.requireView(checkNotNull(entry.summary)),
+ listContainer)
+ else -> throw RuntimeException(
+ "Unexpected entry type for ${entry.key}: ${entry.javaClass}")
+ }
+ }
+ }
+}
+
+class NotifViewManagerBuilder @Inject constructor(
+ private val viewBarn: NotifViewBarn,
+ private val logger: NotifViewManagerLogger
+) {
+ fun build(listContainer: NotificationListContainer): NotifViewManager {
+ return NotifViewManager(listContainer, viewBarn, logger)
+ }
+}
+
+private fun isAttachedToRootEntry(entry: ListEntry?): Boolean {
+ return when (entry) {
+ null -> false
+ ROOT_ENTRY -> true
+ else -> isAttachedToRootEntry(entry.parent)
+ }
+}
+
+private interface Node {
+ val entry: ListEntry
+ val nodeParent: ParentNode?
+}
+
+private interface ParentNode : Node {
+ fun getChildViewAt(index: Int): View?
+ fun addChildAt(child: RowNode, index: Int)
+ fun moveChild(child: RowNode, index: Int)
+ fun removeChild(child: RowNode, isTransfer: Boolean)
+}
+
+private interface RowNode : Node {
+ val view: ExpandableNotificationRow
+ override var nodeParent: ParentNode?
+}
+
+private class RootWrapper(
+ private val listContainer: NotificationListContainer
+) : ParentNode {
+ override val entry: ListEntry = ROOT_ENTRY
+ override val nodeParent: ParentNode? = null
+
+ override fun getChildViewAt(index: Int): View? {
+ return listContainer.getContainerChildAt(index)
+ }
+
+ override fun addChildAt(child: RowNode, index: Int) {
+ listContainer.addContainerViewAt(child.view, index)
+ }
+
+ override fun moveChild(child: RowNode, index: Int) {
+ listContainer.changeViewPosition(child.view, index)
+ }
+
+ override fun removeChild(child: RowNode, isTransfer: Boolean) {
+ if (isTransfer) {
+ listContainer.setChildTransferInProgress(true)
+ }
+ listContainer.removeContainerView(child.view)
+ if (isTransfer) {
+ listContainer.setChildTransferInProgress(false)
+ }
+ }
+}
+
+private class GroupWrapper(
+ override val entry: GroupEntry,
+ override val view: ExpandableNotificationRow,
+ val listContainer: NotificationListContainer
+) : RowNode, ParentNode {
+
+ override var nodeParent: ParentNode? = null
+
+ override fun getChildViewAt(index: Int): View? {
+ return view.getChildNotificationAt(index)
+ }
+
+ override fun addChildAt(child: RowNode, index: Int) {
+ view.addChildNotification(child.view, index)
+ listContainer.notifyGroupChildAdded(child.view)
+ }
+
+ override fun moveChild(child: RowNode, index: Int) {
+ view.removeChildNotification(child.view)
+ view.addChildNotification(child.view, index)
+ }
+
+ override fun removeChild(child: RowNode, isTransfer: Boolean) {
+ view.removeChildNotification(child.view)
+ if (isTransfer) {
+ listContainer.notifyGroupChildRemoved(child.view, view)
+ }
+ }
+}
+
+private class RowWrapper(
+ override val entry: NotificationEntry,
+ override val view: ExpandableNotificationRow
+) : RowNode {
+ override var nodeParent: ParentNode? = null
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt
new file mode 100644
index 000000000000..3d561264d367
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.systemui.statusbar.notification.collection.render
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.NotificationLog
+import javax.inject.Inject
+
+class NotifViewManagerLogger @Inject constructor(
+ @NotificationLog private val buffer: LogBuffer
+) {
+ fun logDetachingChild(
+ key: String,
+ isTransfer: Boolean,
+ oldParent: String?,
+ newParent: String?
+ ) {
+ buffer.log(TAG, LogLevel.DEBUG, {
+ str1 = key
+ bool1 = isTransfer
+ str2 = oldParent
+ str3 = newParent
+ }, {
+ "Detach $str1 isTransfer=$bool1 oldParent=$str2 newParent=$str3"
+ })
+ }
+
+ fun logSkippingDetach(key: String, parent: String?) {
+ buffer.log(TAG, LogLevel.DEBUG, {
+ str1 = key
+ str2 = parent
+ }, {
+ "Skipping detach of $str1 because its parent $str2 is also being detached"
+ })
+ }
+
+ fun logAttachingChild(key: String, parent: String) {
+ buffer.log(TAG, LogLevel.DEBUG, {
+ str1 = key
+ str2 = parent
+ }, {
+ "Attaching view $str1 to $str2"
+ })
+ }
+
+ fun logMovingChild(key: String, parent: String, toIndex: Int) {
+ buffer.log(TAG, LogLevel.DEBUG, {
+ str1 = key
+ str2 = parent
+ int1 = toIndex
+ }, {
+ "Moving child view $str1 in $str2 to index $int1"
+ })
+ }
+}
+
+private const val TAG = "NotifViewManager" \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index ee471c38315e..046dc3c8dce6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -25,6 +25,7 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background;
@@ -40,11 +41,13 @@ import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFea
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
+import com.android.systemui.statusbar.notification.collection.inflation.OnDismissCallbackImpl;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -58,6 +61,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationPanelLogg
import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.row.OnDismissCallback;
import com.android.systemui.statusbar.notification.row.PriorityOnboardingDialogController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -92,8 +96,7 @@ public interface NotificationsModule {
Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
LeakDetector leakDetector,
ForegroundServiceDismissalFeatureController fgsFeatureController,
- HeadsUpManager headsUpManager,
- StatusBarStateController statusBarStateController) {
+ IStatusBarService statusBarService) {
return new NotificationEntryManager(
logger,
groupManager,
@@ -104,8 +107,7 @@ public interface NotificationsModule {
notificationRemoteInputManagerLazy,
leakDetector,
fgsFeatureController,
- headsUpManager,
- statusBarStateController);
+ statusBarService);
}
/** Provides an instance of {@link NotificationGutsManager} */
@@ -219,6 +221,28 @@ public interface NotificationsModule {
return featureFlags.isNewNotifPipelineRenderingEnabled() ? pipeline.get() : entryManager;
}
+ /**
+ * Provide a dismissal callback that's triggered when a user manually dismissed a notification
+ * from the notification shade or it gets auto-cancelled by click.
+ */
+ @Provides
+ @Singleton
+ static OnDismissCallback provideOnDismissCallback(
+ FeatureFlags featureFlags,
+ HeadsUpManager headsUpManager,
+ StatusBarStateController statusBarStateController,
+ Lazy<NotifPipeline> pipeline,
+ Lazy<NotifCollection> notifCollection,
+ NotificationEntryManager entryManager) {
+ return featureFlags.isNewNotifPipelineRenderingEnabled()
+ ? new OnDismissCallbackImpl(
+ pipeline.get(), notifCollection.get(), headsUpManager,
+ statusBarStateController)
+ : new com.android.systemui.statusbar.notification.collection
+ .legacy.OnDismissCallbackImpl(
+ entryManager, headsUpManager, statusBarStateController);
+ }
+
/** */
@Binds
NotificationInterruptStateProvider bindNotificationInterruptStateProvider(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d1ce8d1cf4c7..22d0357b14c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL;
+
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
@@ -92,7 +94,6 @@ import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationListItem;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.SwipeableView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -115,8 +116,7 @@ import java.util.function.Consumer;
* the group summary (which contains 1 or more child notifications).
*/
public class ExpandableNotificationRow extends ActivatableNotificationView
- implements PluginListener<NotificationMenuRowPlugin>, SwipeableView,
- NotificationListItem {
+ implements PluginListener<NotificationMenuRowPlugin>, SwipeableView {
private static final boolean DEBUG = false;
private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
@@ -323,7 +323,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private View mGroupParentWhenDismissed;
private boolean mShelfIconVisible;
private boolean mAboveShelf;
- private Runnable mOnDismissRunnable;
+ private OnDismissCallback mOnDismissCallback;
private boolean mIsLowPriority;
private boolean mIsColorized;
private boolean mUseIncreasedCollapsedHeight;
@@ -801,17 +801,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
row.setIsChildInGroup(true, this);
}
- /**
- * Same as {@link #addChildNotification(ExpandableNotificationRow, int)}, but takes a
- * {@link NotificationListItem} instead
- *
- * @param childItem item
- * @param childIndex index
- */
- public void addChildNotification(NotificationListItem childItem, int childIndex) {
- addChildNotification((ExpandableNotificationRow) childItem.getView(), childIndex);
- }
-
public void removeChildNotification(ExpandableNotificationRow row) {
if (mChildrenContainer != null) {
mChildrenContainer.removeNotification(row);
@@ -821,9 +810,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
row.setBottomRoundness(0.0f, false /* animate */);
}
- @Override
- public void removeChildNotification(NotificationListItem child) {
- removeChildNotification((ExpandableNotificationRow) child.getView());
+ /** Returns the child notification at [index], or null if no such child. */
+ @Nullable
+ public ExpandableNotificationRow getChildNotificationAt(int index) {
+ if (mChildrenContainer == null
+ || mChildrenContainer.getAttachedChildren().size() <= index) {
+ return null;
+ } else {
+ return mChildrenContainer.getAttachedChildren().get(index);
+ }
}
@Override
@@ -914,7 +909,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
* @param callback the callback to invoked in case it is not allowed
* @return whether the list order has changed
*/
- public boolean applyChildOrder(List<? extends NotificationListItem> childOrder,
+ public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
VisualStabilityManager visualStabilityManager,
VisualStabilityManager.Callback callback) {
return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder,
@@ -1321,11 +1316,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
onAttachedChildrenCountChanged();
}
- @Override
- public View getView() {
- return this;
- }
-
public void setForceUnlocked(boolean forceUnlocked) {
mForceUnlocked = forceUnlocked;
if (mIsSummaryWithChildren) {
@@ -1456,10 +1446,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
dismiss(fromAccessibility);
if (mEntry.isClearable()) {
- // TODO: beverlyt, log dismissal
- // TODO: track dismiss sentiment
- if (mOnDismissRunnable != null) {
- mOnDismissRunnable.run();
+ if (mOnDismissCallback != null) {
+ mOnDismissCallback.onDismiss(mEntry, REASON_CANCEL);
}
}
}
@@ -1476,8 +1464,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mIsBlockingHelperShowing && mNotificationTranslationFinished;
}
- void setOnDismissRunnable(Runnable onDismissRunnable) {
- mOnDismissRunnable = onDismissRunnable;
+ void setOnDismissCallback(OnDismissCallback onDismissCallback) {
+ mOnDismissCallback = onDismissCallback;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index c9839355b9ba..86a3271c4eac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -30,7 +30,6 @@ import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.dagger.AppName;
-import com.android.systemui.statusbar.notification.row.dagger.DismissRunnable;
import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -66,7 +65,7 @@ public class ExpandableNotificationRowController {
private final ExpandableNotificationRow.CoordinateOnClickListener mOnAppOpsClickListener;
private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
private final NotificationGutsManager mNotificationGutsManager;
- private Runnable mOnDismissRunnable;
+ private final OnDismissCallback mOnDismissCallback;
private final FalsingManager mFalsingManager;
private final boolean mAllowLongPress;
private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
@@ -84,7 +83,7 @@ public class ExpandableNotificationRowController {
StatusBarStateController statusBarStateController,
NotificationGutsManager notificationGutsManager,
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
- @DismissRunnable Runnable onDismissRunnable, FalsingManager falsingManager,
+ OnDismissCallback onDismissCallback, FalsingManager falsingManager,
PeopleNotificationIdentifier peopleNotificationIdentifier) {
mView = view;
mActivatableNotificationViewController = activatableNotificationViewController;
@@ -101,7 +100,7 @@ public class ExpandableNotificationRowController {
mOnExpandClickListener = onExpandClickListener;
mStatusBarStateController = statusBarStateController;
mNotificationGutsManager = notificationGutsManager;
- mOnDismissRunnable = onDismissRunnable;
+ mOnDismissCallback = onDismissCallback;
mOnAppOpsClickListener = mNotificationGutsManager::openGuts;
mOnFeedbackClickListener = mNotificationGutsManager::openGuts;
mAllowLongPress = allowLongPress;
@@ -130,7 +129,7 @@ public class ExpandableNotificationRowController {
mStatusBarStateController,
mPeopleNotificationIdentifier
);
- mView.setOnDismissRunnable(mOnDismissRunnable);
+ mView.setOnDismissCallback(mOnDismissCallback);
mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (mAllowLongPress) {
mView.setLongPressListener((v, x, y, item) -> {
@@ -163,10 +162,4 @@ public class ExpandableNotificationRowController {
private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
mNotificationLogger.onExpansionChanged(key, userAction, expanded);
}
-
- /** */
- public void setOnDismissRunnable(Runnable onDismissRunnable) {
- mOnDismissRunnable = onDismissRunnable;
- mView.setOnDismissRunnable(onDismissRunnable);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java
new file mode 100644
index 000000000000..f1aed899e060
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.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.systemui.statusbar.notification.row;
+
+import android.service.notification.NotificationListenerService;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+/**
+ * Callback when a user clicks on an auto-cancelled notification or manually swipes to dismiss the
+ * notification.
+ */
+public interface OnDismissCallback {
+
+ /**
+ * Handle a user interaction that triggers a notification dismissal.
+ */
+ void onDismiss(
+ NotificationEntry entry,
+ @NotificationListenerService.NotificationCancelReason int cancellationReason);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
index 321656df504a..28ddf5971bcb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
@@ -54,8 +54,6 @@ public interface ExpandableNotificationRowComponent {
@BindsInstance
Builder notificationEntry(NotificationEntry entry);
@BindsInstance
- Builder onDismissRunnable(@DismissRunnable Runnable runnable);
- @BindsInstance
Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter);
ExpandableNotificationRowComponent build();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 907b89040a28..93c2377ccfae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -447,7 +447,7 @@ public class NotificationChildrenContainer extends ViewGroup {
* @param callback
* @return whether the list order has changed
*/
- public boolean applyChildOrder(List<? extends NotificationListItem> childOrder,
+ public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
VisualStabilityManager visualStabilityManager,
VisualStabilityManager.Callback callback) {
if (childOrder == null) {
@@ -456,7 +456,7 @@ public class NotificationChildrenContainer extends ViewGroup {
boolean result = false;
for (int i = 0; i < mAttachedChildren.size() && i < childOrder.size(); i++) {
ExpandableNotificationRow child = mAttachedChildren.get(i);
- ExpandableNotificationRow desiredChild = (ExpandableNotificationRow) childOrder.get(i);
+ ExpandableNotificationRow desiredChild = childOrder.get(i);
if (child != desiredChild) {
if (visualStabilityManager.canReorderNotification(desiredChild)) {
mAttachedChildren.remove(desiredChild);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 09ab1d89473e..72f32161038a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -18,15 +18,15 @@ package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
-import android.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.Nullable;
+
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.SimpleNotificationListContainer;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -35,8 +35,9 @@ import com.android.systemui.statusbar.notification.row.ExpandableView;
* Interface representing the entity that contains notifications. It can have
* notification views added and removed from it, and will manage displaying them to the user.
*/
-public interface NotificationListContainer extends ExpandableView.OnHeightChangedListener,
- VisibilityLocationProvider, SimpleNotificationListContainer {
+public interface NotificationListContainer extends
+ ExpandableView.OnHeightChangedListener,
+ VisibilityLocationProvider {
/**
* Called when a child is being transferred.
@@ -91,6 +92,7 @@ public interface NotificationListContainer extends ExpandableView.OnHeightChange
* @param i ith child to get
* @return the ith child in the list container
*/
+ @Nullable
View getContainerChildAt(int i);
/**
@@ -108,6 +110,11 @@ public interface NotificationListContainer extends ExpandableView.OnHeightChange
void addContainerView(View v);
/**
+ * Add a view to the container at a particular index
+ */
+ void addContainerViewAt(View v, int index);
+
+ /**
* Sets the maximum number of notifications to display.
*
* @param maxNotifications max number of notifications to display
@@ -188,13 +195,10 @@ public interface NotificationListContainer extends ExpandableView.OnHeightChange
return true;
}
- default void setWillExpand(boolean willExpand) {};
-
/**
- * Remove a list item from the container
- * @param v the item to remove
+ * Tells the container that an animation is about to expand it.
*/
- void removeListItem(@NonNull NotificationListItem v);
+ default void setWillExpand(boolean willExpand) {}
void setNotificationActivityStarter(NotificationActivityStarter notificationActivityStarter);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java
deleted file mode 100644
index c2dd2296aa17..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java
+++ /dev/null
@@ -1,69 +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.
- */
-
-package com.android.systemui.statusbar.notification.stack;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-import java.util.List;
-
-/**
-* A NotificationListItem is a child view of the notification list that can yield a
-* NotificationEntry when asked. I.e., it's an ExpandableNotificationRow but doesn't require us
-* to strictly rely on ExpandableNotificationRow as our consumed type
- */
-public interface NotificationListItem {
- /** @return entry for this item */
- @NonNull
- NotificationEntry getEntry();
-
- /** @return true if the blocking helper is showing */
- boolean isBlockingHelperShowing();
-
- /** @return true if this list item is a summary with children */
- boolean isSummaryWithChildren();
-
- // This generic is kind of ugly - we should change this once the old VHM is gone
- /** @return list of the children of this item */
- List<? extends NotificationListItem> getAttachedChildren();
-
- /** remove all children from this list item */
- void removeAllChildren();
-
- /** remove particular child */
- void removeChildNotification(NotificationListItem child);
-
- /** add an item as a child */
- void addChildNotification(NotificationListItem child, int childIndex);
-
- /** set the child count view should display */
- void setUntruncatedChildCount(int count);
-
- /** Update the order of the children with the new list */
- boolean applyChildOrder(
- List<? extends NotificationListItem> childOrderList,
- VisualStabilityManager vsm,
- @Nullable VisualStabilityManager.Callback callback);
-
- /** return the associated view for this list item */
- @NonNull
- View getView();
-}
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 b9d31a93f408..66a541a923a4 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
@@ -11,7 +11,7 @@
* 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
+ * limitations under the License.
*/
package com.android.systemui.statusbar.notification.stack;
@@ -3387,21 +3387,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@Override
- public void notifyGroupChildRemoved(View child, ViewGroup parent) {
- notifyGroupChildRemoved((ExpandableView) child, parent);
- }
-
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void notifyGroupChildAdded(ExpandableView row) {
onViewAddedInternal(row);
}
- @Override
- public void notifyGroupChildAdded(View view) {
- notifyGroupChildAdded((ExpandableView) view);
- }
-
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void setAnimationsEnabled(boolean animationsEnabled) {
mAnimationsEnabled = animationsEnabled;
@@ -5246,20 +5236,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void removeListItem(NotificationListItem v) {
- removeContainerView(v.getView());
- }
-
- @Override
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void addContainerView(View v) {
Assert.isMainThread();
addView(v);
}
@Override
- public void addListItem(NotificationListItem v) {
- addContainerView(v.getView());
+ public void addContainerViewAt(View v, int index) {
+ Assert.isMainThread();
+ addView(v, index);
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -6596,40 +6581,25 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
} else {
final List<Pair<NotificationEntry, DismissedByUserStats>>
entriesWithRowsDismissedFromShade = new ArrayList<>();
- final List<DismissedByUserStats> dismissalUserStats = new ArrayList<>();
final int numVisibleEntries = mNotifPipeline.getShadeListCount();
for (int i = 0; i < viewsToRemove.size(); i++) {
final NotificationEntry entry = viewsToRemove.get(i).getEntry();
- final DismissedByUserStats stats =
- new DismissedByUserStats(
- DISMISSAL_SHADE,
- DISMISS_SENTIMENT_NEUTRAL,
- NotificationVisibility.obtain(
- entry.getKey(),
- entry.getRanking().getRank(),
- numVisibleEntries,
- true,
- NotificationLogger.getNotificationLocation(entry)));
entriesWithRowsDismissedFromShade.add(
- new Pair<NotificationEntry, DismissedByUserStats>(entry, stats));
+ new Pair<NotificationEntry, DismissedByUserStats>(
+ entry,
+ getDismissedByUserStats(entry, numVisibleEntries)));
}
mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
}
} else {
for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
if (canChildBeDismissed(rowToRemove)) {
- if (selectedRows == ROWS_ALL) {
- // TODO: This is a listener method; we shouldn't be calling it. Can we just
- // call performRemoveNotification as below?
- mEntryManager.removeNotification(
- rowToRemove.getEntry().getKey(),
- null /* ranking */,
- NotificationListenerService.REASON_CANCEL_ALL);
- } else {
- mEntryManager.performRemoveNotification(
- rowToRemove.getEntry().getSbn(),
- NotificationListenerService.REASON_CANCEL_ALL);
- }
+ mEntryManager.performRemoveNotification(
+ rowToRemove.getEntry().getSbn(),
+ getDismissedByUserStats(
+ rowToRemove.getEntry(),
+ mEntryManager.getActiveNotificationsCount()),
+ NotificationListenerService.REASON_CANCEL_ALL);
} else {
rowToRemove.resetTranslation();
}
@@ -6643,6 +6613,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
+ private DismissedByUserStats getDismissedByUserStats(
+ NotificationEntry entry,
+ int numVisibleEntries
+ ) {
+ return new DismissedByUserStats(
+ DISMISSAL_SHADE,
+ DISMISS_SENTIMENT_NEUTRAL,
+ NotificationVisibility.obtain(
+ entry.getKey(),
+ entry.getRanking().getRank(),
+ numVisibleEntries,
+ true,
+ NotificationLogger.getNotificationLocation(entry)));
+ }
+
// ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
@ShadeViewRefactor(RefactorComponent.INPUT)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 303a0831b52f..0e76c904f8cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -152,6 +152,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private final Context mContext;
private final int mWakeUpDelay;
private int mMode;
+ private BiometricSourceType mBiometricType;
private KeyguardViewController mKeyguardViewController;
private DozeScrimController mDozeScrimController;
private KeyguardViewMediator mKeyguardViewMediator;
@@ -340,6 +341,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
Trace.endSection();
return;
}
+ mBiometricType = biometricSourceType;
mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
.setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
Optional.ofNullable(BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
@@ -615,6 +617,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private void resetMode() {
mMode = MODE_NONE;
+ mBiometricType = null;
mNotificationShadeWindowController.setForceDozeBrightness(false);
if (mStatusBar.getNavigationBarView() != null) {
mStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
@@ -680,8 +683,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
/**
* Successful authentication with fingerprint, face, or iris when the lockscreen fades away
*/
- public boolean isUnlockFading() {
- return mMode == MODE_UNLOCK_FADING;
+ public BiometricSourceType getBiometricType() {
+ return mBiometricType;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index 74d9f5402e36..bfe0684b5411 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -84,7 +84,9 @@ class KeyguardLiftController constructor(
val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
!statusBarStateController.isDozing
- val shouldListen = onKeyguard || bouncerVisible
+ val userId = KeyguardUpdateMonitor.getCurrentUser()
+ val isFaceEnabled = keyguardUpdateMonitor.isFaceAuthEnabledForUser(userId)
+ val shouldListen = (onKeyguard || bouncerVisible) && isFaceEnabled
if (shouldListen != isListening) {
isListening = shouldListen
@@ -95,4 +97,4 @@ class KeyguardLiftController constructor(
}
}
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index 141bdc242861..1dc0f070835b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -83,6 +83,7 @@ public class LockscreenLockIconController {
private boolean mWakeAndUnlockRunning;
private boolean mShowingLaunchAffordance;
private boolean mBouncerShowingScrimmed;
+ private boolean mFingerprintUnlock;
private int mStatusBarState = StatusBarState.SHADE;
private LockIcon mLockIcon;
@@ -377,14 +378,19 @@ public class LockscreenLockIconController {
/**
* We need to hide the lock whenever there's a fingerprint unlock, otherwise you'll see the
* icon on top of the black front scrim.
+ * We also want to halt padlock the animation when we're in face bypass mode or dismissing the
+ * keyguard with fingerprint.
* @param wakeAndUnlock are we wake and unlocking
* @param isUnlock are we currently unlocking
*/
- public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
+ public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock,
+ BiometricSourceType type) {
if (wakeAndUnlock) {
mWakeAndUnlockRunning = true;
}
- if (isUnlock && mKeyguardBypassController.getBypassEnabled() && canBlockUpdates()) {
+ mFingerprintUnlock = type == BiometricSourceType.FINGERPRINT;
+ if (isUnlock && (mFingerprintUnlock || mKeyguardBypassController.getBypassEnabled())
+ && canBlockUpdates()) {
// We don't want the icon to change while we are unlocking
mBlockUpdates = true;
}
@@ -498,10 +504,13 @@ public class LockscreenLockIconController {
private boolean updateIconVisibility() {
boolean onAodOrDocked = mStatusBarStateController.isDozing() && mDocked;
boolean invisible = onAodOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance;
- if (mKeyguardBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
+ boolean fingerprintOrBypass = mFingerprintUnlock
+ || mKeyguardBypassController.getBypassEnabled();
+ if (fingerprintOrBypass && !mBouncerShowingScrimmed) {
if ((mHeadsUpManagerPhone.isHeadsUpGoingAway()
|| mHeadsUpManagerPhone.hasPinnedHeadsUp()
- || mStatusBarState == StatusBarState.KEYGUARD)
+ || mStatusBarState == StatusBarState.KEYGUARD
+ || mStatusBarState == StatusBarState.SHADE)
&& !mNotificationWakeUpCoordinator.getNotificationsFullyHidden()) {
invisible = true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 5266e25b326c..6297052550c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -1211,6 +1211,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
private void updateAccessibilityServicesState(AccessibilityManager accessibilityManager) {
+ if (mNavigationBarView == null) {
+ return;
+ }
boolean[] feedbackEnabled = new boolean[1];
int a11yFlags = getA11yButtonState(feedbackEnabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 375af6b099c2..99cb4760a8d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -62,7 +62,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
-import com.android.keyguard.KeyguardClockSwitch;
+import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -124,6 +124,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import javax.inject.Inject;
+import javax.inject.Provider;
@StatusBarComponent.StatusBarScope
public class NotificationPanelViewController extends PanelViewController {
@@ -252,6 +253,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final ConversationNotificationManager mConversationNotificationManager;
private final MediaHierarchyManager mMediaHierarchyManager;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final Provider<KeyguardClockSwitchController> mKeyguardClockSwitchControllerProvider;
private KeyguardAffordanceHelper mAffordanceHelper;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -495,7 +497,8 @@ public class NotificationPanelViewController extends PanelViewController {
ConversationNotificationManager conversationNotificationManager,
MediaHierarchyManager mediaHierarchyManager,
BiometricUnlockController biometricUnlockController,
- StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ Provider<KeyguardClockSwitchController> keyguardClockSwitchControllerProvider) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager);
@@ -507,6 +510,7 @@ public class NotificationPanelViewController extends PanelViewController {
mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder;
mMediaHierarchyManager = mediaHierarchyManager;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ mKeyguardClockSwitchControllerProvider = keyguardClockSwitchControllerProvider;
mView.setWillNotDraw(!DEBUG);
mInjectionInflationController = injectionInflationController;
mFalsingManager = falsingManager;
@@ -579,9 +583,11 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
mKeyguardStatusView = mView.findViewById(R.id.keyguard_status_view);
- KeyguardClockSwitch keyguardClockSwitch = mView.findViewById(R.id.keyguard_clock_container);
+ KeyguardClockSwitchController keyguardClockSwitchController =
+ mKeyguardClockSwitchControllerProvider.get();
+ keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container));
mBigClockContainer = mView.findViewById(R.id.big_clock_container);
- keyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
mNotificationStackScroller = mView.findViewById(R.id.notification_stack_scroller);
@@ -703,8 +709,10 @@ public class NotificationPanelViewController extends PanelViewController {
// Re-associate the clock container with the keyguard clock switch.
mBigClockContainer.removeAllViews();
- KeyguardClockSwitch keyguardClockSwitch = mView.findViewById(R.id.keyguard_clock_container);
- keyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ KeyguardClockSwitchController keyguardClockSwitchController =
+ mKeyguardClockSwitchControllerProvider.get();
+ keyguardClockSwitchController.attach(mView.findViewById(R.id.keyguard_clock_container));
+ keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
// Update keyguard bottom area
index = mView.indexOfChild(mKeyguardBottomArea);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index e942d85790c1..ac329e2598a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -408,7 +408,7 @@ public abstract class PanelViewController {
&& !mKeyguardStateController.isKeyguardFadingAway()) {
long timePassed = SystemClock.uptimeMillis() - mDownTime;
if (timePassed < ViewConfiguration.getLongPressTimeout()) {
- // Lets show the user that he can actually expand the panel
+ // Let's show the user that they can actually expand the panel
runPeekAnimation(
PEEK_ANIMATION_DURATION, getPeekHeight(), true /* collapseWhenFinished */);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c5571e8ceb20..eb626280b494 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3975,7 +3975,8 @@ public class StatusBar extends SystemUI implements DemoMode,
updateScrimController();
mLockscreenLockIconController.onBiometricAuthModeChanged(
mBiometricUnlockController.isWakeAndUnlock(),
- mBiometricUnlockController.isBiometricUnlock());
+ mBiometricUnlockController.isBiometricUnlock(),
+ mBiometricUnlockController.getBiometricType());
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 3ae84ecfc2f0..b89cb210dea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -79,15 +79,16 @@ public interface StatusBarIconController {
public void removeIcon(String slot, int tag);
public void removeAllIconsForSlot(String slot);
- public static final String ICON_BLACKLIST = "icon_blacklist";
+ // TODO: See if we can rename this tunable name.
+ String ICON_HIDE_LIST = "icon_blacklist";
- /** Reads the default blacklist from config value unless blacklistStr is provided. */
- static ArraySet<String> getIconBlacklist(Context context, String blackListStr) {
+ /** Reads the default hide list from config value unless hideListStr is provided. */
+ static ArraySet<String> getIconHideList(Context context, String hideListStr) {
ArraySet<String> ret = new ArraySet<>();
- String[] blacklist = blackListStr == null
+ String[] hideList = hideListStr == null
? context.getResources().getStringArray(R.array.config_statusBarIconBlackList)
- : blackListStr.split(",");
- for (String slot : blacklist) {
+ : hideListStr.split(",");
+ for (String slot : hideList) {
if (!TextUtils.isEmpty(slot)) {
ret.add(slot);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index d0e806769f14..21e1d319cffa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -59,7 +59,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
private static final String TAG = "StatusBarIconController";
private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
- private final ArraySet<String> mIconBlacklist = new ArraySet<>();
+ private final ArraySet<String> mIconHideList = new ArraySet<>();
// Points to light or dark context depending on the... context?
private Context mContext;
@@ -79,7 +79,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
loadDimens();
commandQueue.addCallback(this);
- Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, ICON_HIDE_LIST);
}
@Override
@@ -89,12 +89,12 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
for (int i = 0; i < allSlots.size(); i++) {
Slot slot = allSlots.get(i);
List<StatusBarIconHolder> holders = slot.getHolderListInViewOrder();
- boolean blocked = mIconBlacklist.contains(slot.getName());
+ boolean hidden = mIconHideList.contains(slot.getName());
for (StatusBarIconHolder holder : holders) {
int tag = holder.getTag();
int viewIndex = getViewIndex(getSlotIndex(slot.getName()), holder.getTag());
- group.onIconAdded(viewIndex, slot.getName(), blocked, holder);
+ group.onIconAdded(viewIndex, slot.getName(), hidden, holder);
}
}
}
@@ -107,11 +107,11 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
@Override
public void onTuningChanged(String key, String newValue) {
- if (!ICON_BLACKLIST.equals(key)) {
+ if (!ICON_HIDE_LIST.equals(key)) {
return;
}
- mIconBlacklist.clear();
- mIconBlacklist.addAll(StatusBarIconController.getIconBlacklist(mContext, newValue));
+ mIconHideList.clear();
+ mIconHideList.addAll(StatusBarIconController.getIconHideList(mContext, newValue));
ArrayList<Slot> currentSlots = getSlots();
ArrayMap<Slot, List<StatusBarIconHolder>> slotsToReAdd = new ArrayMap<>();
@@ -142,9 +142,9 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
private void addSystemIcon(int index, StatusBarIconHolder holder) {
String slot = getSlotName(index);
int viewIndex = getViewIndex(index, holder.getTag());
- boolean blocked = mIconBlacklist.contains(slot);
+ boolean hidden = mIconHideList.contains(slot);
- mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, blocked, holder));
+ mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, hidden, holder));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 7bcfb466d7d9..4de648402464 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
import static android.service.notification.NotificationListenerService.REASON_CLICK;
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions;
@@ -37,7 +36,6 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
-import android.service.notification.NotificationStats;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.EventLog;
@@ -71,11 +69,11 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.OnDismissCallback;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -128,6 +126,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final NotificationPresenter mPresenter;
private final NotificationPanelViewController mNotificationPanel;
private final ActivityLaunchAnimator mActivityLaunchAnimator;
+ private final OnDismissCallback mOnDismissCallback;
private boolean mIsCollapsingToShowActivityOverLockscreen;
@@ -162,6 +161,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
FeatureFlags featureFlags,
MetricsLogger metricsLogger,
StatusBarNotificationActivityStarterLogger logger,
+ OnDismissCallback onDismissCallback,
StatusBar statusBar,
NotificationPresenter presenter,
@@ -197,6 +197,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mFeatureFlags = featureFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
+ mOnDismissCallback = onDismissCallback;
// TODO: use KeyguardStateController#isOccluded to remove this dependency
mStatusBar = statusBar;
@@ -574,13 +575,14 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private void removeNotification(NotificationEntry entry) {
// We have to post it to the UI thread for synchronization
mMainThreadHandler.post(() -> {
- Runnable removeRunnable = createRemoveRunnable(entry);
if (mPresenter.isCollapsing()) {
// To avoid lags we're only performing the remove
// after the shade was collapsed
- mShadeController.addPostCollapseAction(removeRunnable);
+ mShadeController.addPostCollapseAction(
+ () -> mOnDismissCallback.onDismiss(entry, REASON_CLICK)
+ );
} else {
- removeRunnable.run();
+ mOnDismissCallback.onDismiss(entry, REASON_CLICK);
}
});
}
@@ -595,43 +597,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
}
}
- private Runnable createRemoveRunnable(NotificationEntry entry) {
- if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- return new Runnable() {
- @Override
- public void run() {
- // see NotificationLogger#logNotificationClear
- int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
- if (mHeadsUpManager.isAlerting(entry.getKey())) {
- dismissalSurface = NotificationStats.DISMISSAL_PEEK;
- } else if (mNotificationPanel.hasPulsingNotifications()) {
- dismissalSurface = NotificationStats.DISMISSAL_AOD;
- }
-
- mNotifCollection.dismissNotification(
- entry,
- new DismissedByUserStats(
- dismissalSurface,
- DISMISS_SENTIMENT_NEUTRAL,
- NotificationVisibility.obtain(
- entry.getKey(),
- entry.getRanking().getRank(),
- mNotifPipeline.getShadeListCount(),
- true,
- NotificationLogger.getNotificationLocation(entry))
- ));
- }
- };
- } else {
- return new Runnable() {
- @Override
- public void run() {
- mEntryManager.performRemoveNotification(entry.getSbn(), REASON_CLICK);
- }
- };
- }
- }
-
/**
* Public builder for {@link StatusBarNotificationActivityStarter}.
*/
@@ -667,6 +632,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final FeatureFlags mFeatureFlags;
private final MetricsLogger mMetricsLogger;
private final StatusBarNotificationActivityStarterLogger mLogger;
+ private final OnDismissCallback mOnDismissCallback;
private StatusBar mStatusBar;
private NotificationPresenter mNotificationPresenter;
@@ -704,7 +670,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
FeatureFlags featureFlags,
MetricsLogger metricsLogger,
- StatusBarNotificationActivityStarterLogger logger) {
+ StatusBarNotificationActivityStarterLogger logger,
+ OnDismissCallback onDismissCallback) {
mContext = context;
mCommandQueue = commandQueue;
@@ -736,6 +703,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mFeatureFlags = featureFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
+ mOnDismissCallback = onDismissCallback;
}
/** Sets the status bar to use as {@link StatusBar}. */
@@ -793,6 +761,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mFeatureFlags,
mMetricsLogger,
mLogger,
+ mOnDismissCallback,
mStatusBar,
mNotificationPresenter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 690d57345db6..7eefaf28517e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -52,12 +52,12 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
private final SecurityController mSecurityController;
private final Handler mHandler = Handler.getMain();
- private boolean mBlockAirplane;
- private boolean mBlockMobile;
- private boolean mBlockWifi;
- private boolean mBlockEthernet;
+ private boolean mHideAirplane;
+ private boolean mHideMobile;
+ private boolean mHideWifi;
+ private boolean mHideEthernet;
private boolean mActivityEnabled;
- private boolean mForceBlockWifi;
+ private boolean mForceHideWifi;
// Track as little state as possible, and only for padding purposes
private boolean mIsAirplaneMode = false;
@@ -80,7 +80,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
mNetworkController = Dependency.get(NetworkController.class);
mSecurityController = Dependency.get(SecurityController.class);
- Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_HIDE_LIST);
mNetworkController.addCallback(this);
mSecurityController.addCallback(this);
}
@@ -114,21 +114,21 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
@Override
public void onTuningChanged(String key, String newValue) {
- if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+ if (!StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
return;
}
- ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(mContext, newValue);
- boolean blockAirplane = blockList.contains(mSlotAirplane);
- boolean blockMobile = blockList.contains(mSlotMobile);
- boolean blockWifi = blockList.contains(mSlotWifi);
- boolean blockEthernet = blockList.contains(mSlotEthernet);
-
- if (blockAirplane != mBlockAirplane || blockMobile != mBlockMobile
- || blockEthernet != mBlockEthernet || blockWifi != mBlockWifi) {
- mBlockAirplane = blockAirplane;
- mBlockMobile = blockMobile;
- mBlockEthernet = blockEthernet;
- mBlockWifi = blockWifi || mForceBlockWifi;
+ ArraySet<String> hideList = StatusBarIconController.getIconHideList(mContext, newValue);
+ boolean hideAirplane = hideList.contains(mSlotAirplane);
+ boolean hideMobile = hideList.contains(mSlotMobile);
+ boolean hideWifi = hideList.contains(mSlotWifi);
+ boolean hideEthernet = hideList.contains(mSlotEthernet);
+
+ if (hideAirplane != mHideAirplane || hideMobile != mHideMobile
+ || hideEthernet != mHideEthernet || hideWifi != mHideWifi) {
+ mHideAirplane = hideAirplane;
+ mHideMobile = hideMobile;
+ mHideEthernet = hideEthernet;
+ mHideWifi = hideWifi || mForceHideWifi;
// Re-register to get new callbacks.
mNetworkController.removeCallback(this);
mNetworkController.addCallback(this);
@@ -140,7 +140,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
boolean activityIn, boolean activityOut, String description, boolean isTransient,
String statusLabel) {
- boolean visible = statusIcon.visible && !mBlockWifi;
+ boolean visible = statusIcon.visible && !mHideWifi;
boolean in = activityIn && mActivityEnabled && visible;
boolean out = activityOut && mActivityEnabled && visible;
@@ -189,7 +189,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
// Visibility of the data type indicator changed
boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0);
- state.visible = statusIcon.visible && !mBlockMobile;
+ state.visible = statusIcon.visible && !mHideMobile;
state.strengthId = statusIcon.icon;
state.typeId = statusType;
state.contentDescription = statusIcon.contentDescription;
@@ -270,7 +270,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
@Override
public void setEthernetIndicators(IconState state) {
- boolean visible = state.visible && !mBlockEthernet;
+ boolean visible = state.visible && !mHideEthernet;
int resId = state.icon;
String description = state.contentDescription;
@@ -284,7 +284,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
@Override
public void setIsAirplaneMode(IconState icon) {
- mIsAirplaneMode = icon.visible && !mBlockAirplane;
+ mIsAirplaneMode = icon.visible && !mHideAirplane;
int resId = icon.icon;
String description = icon.contentDescription;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index d30f01a658f6..88a6263c1dca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -74,7 +74,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
protected boolean mPowerSave;
private boolean mAodPowerSave;
protected boolean mWirelessCharging;
- private boolean mTestmode = false;
+ private boolean mTestMode = false;
@VisibleForTesting
boolean mHasReceivedBattery = false;
private Estimate mEstimate;
@@ -154,7 +154,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
public void onReceive(final Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- if (mTestmode && !intent.getBooleanExtra("testmode", false)) return;
+ if (mTestMode && !intent.getBooleanExtra("testmode", false)) return;
mHasReceivedBattery = true;
mLevel = (int)(100f
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
@@ -172,29 +172,29 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
updatePowerSave();
} else if (action.equals(ACTION_LEVEL_TEST)) {
- mTestmode = true;
+ mTestMode = true;
mMainHandler.post(new Runnable() {
int curLevel = 0;
int incr = 1;
int saveLevel = mLevel;
boolean savePlugged = mPluggedIn;
- Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ Intent mTestIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
@Override
public void run() {
if (curLevel < 0) {
- mTestmode = false;
- dummy.putExtra("level", saveLevel);
- dummy.putExtra("plugged", savePlugged);
- dummy.putExtra("testmode", false);
+ mTestMode = false;
+ mTestIntent.putExtra("level", saveLevel);
+ mTestIntent.putExtra("plugged", savePlugged);
+ mTestIntent.putExtra("testmode", false);
} else {
- dummy.putExtra("level", curLevel);
- dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
+ mTestIntent.putExtra("level", curLevel);
+ mTestIntent.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
: 0);
- dummy.putExtra("testmode", true);
+ mTestIntent.putExtra("testmode", true);
}
- context.sendBroadcast(dummy);
+ context.sendBroadcast(mTestIntent);
- if (!mTestmode) return;
+ if (!mTestMode) return;
curLevel += incr;
if (curLevel == 100) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 95601955ec04..120a0e3abba4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -191,7 +191,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C
mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter,
Dependency.get(Dependency.TIME_TICK_HANDLER), UserHandle.ALL);
Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
- StatusBarIconController.ICON_BLACKLIST);
+ StatusBarIconController.ICON_HIDE_LIST);
mCommandQueue.addCallback(this);
if (mShowDark) {
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
@@ -305,8 +305,8 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C
if (CLOCK_SECONDS.equals(key)) {
mShowSeconds = TunerService.parseIntegerSwitch(newValue, false);
updateShowSeconds();
- } else {
- setClockVisibleByUser(!StatusBarIconController.getIconBlacklist(getContext(), newValue)
+ } else if (StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
+ setClockVisibleByUser(!StatusBarIconController.getIconHideList(getContext(), newValue)
.contains("clock"));
updateClockVisibility();
}
@@ -404,7 +404,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C
mContentDescriptionFormat = new SimpleDateFormat(format);
/*
* Search for an unquoted "a" in the format string, so we can
- * add dummy characters around it to let us find it again after
+ * add marker characters around it to let us find it again after
* formatting and change its size.
*/
if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
index 66372c311325..b71aafdf6b96 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
@@ -38,7 +38,7 @@ public class BatteryPreference extends DropDownPreference implements TunerServic
private final String mBattery;
private boolean mBatteryEnabled;
private boolean mHasPercentage;
- private ArraySet<String> mBlacklist;
+ private ArraySet<String> mHideList;
private boolean mHasSetValue;
public BatteryPreference(Context context, AttributeSet attrs) {
@@ -52,7 +52,7 @@ public class BatteryPreference extends DropDownPreference implements TunerServic
super.onAttached();
mHasPercentage = Settings.System.getInt(getContext().getContentResolver(),
SHOW_BATTERY_PERCENT, 0) != 0;
- Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_HIDE_LIST);
}
@Override
@@ -63,9 +63,9 @@ public class BatteryPreference extends DropDownPreference implements TunerServic
@Override
public void onTuningChanged(String key, String newValue) {
- if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
- mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
- mBatteryEnabled = !mBlacklist.contains(mBattery);
+ if (StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
+ mHideList = StatusBarIconController.getIconHideList(getContext(), newValue);
+ mBatteryEnabled = !mHideList.contains(mBattery);
}
if (!mHasSetValue) {
// Because of the complicated tri-state it can end up looping and setting state back to
@@ -88,12 +88,12 @@ public class BatteryPreference extends DropDownPreference implements TunerServic
MetricsLogger.action(getContext(), MetricsEvent.TUNER_BATTERY_PERCENTAGE, v);
Settings.System.putInt(getContext().getContentResolver(), SHOW_BATTERY_PERCENT, v ? 1 : 0);
if (DISABLED.equals(value)) {
- mBlacklist.add(mBattery);
+ mHideList.add(mBattery);
} else {
- mBlacklist.remove(mBattery);
+ mHideList.remove(mBattery);
}
- Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
- TextUtils.join(",", mBlacklist));
+ Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_HIDE_LIST,
+ TextUtils.join(",", mHideList));
return true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
index f7d0c9fb9d86..c92d7bbfe0b7 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
@@ -33,7 +33,7 @@ public class ClockPreference extends DropDownPreference implements TunerService.
private final String mClock;
private boolean mClockEnabled;
private boolean mHasSeconds;
- private ArraySet<String> mBlacklist;
+ private ArraySet<String> mHideList;
private boolean mHasSetValue;
private boolean mReceivedSeconds;
private boolean mReceivedClock;
@@ -47,7 +47,7 @@ public class ClockPreference extends DropDownPreference implements TunerService.
@Override
public void onAttached() {
super.onAttached();
- Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_HIDE_LIST,
Clock.CLOCK_SECONDS);
}
@@ -59,10 +59,10 @@ public class ClockPreference extends DropDownPreference implements TunerService.
@Override
public void onTuningChanged(String key, String newValue) {
- if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+ if (StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
mReceivedClock = true;
- mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
- mClockEnabled = !mBlacklist.contains(mClock);
+ mHideList = StatusBarIconController.getIconHideList(getContext(), newValue);
+ mClockEnabled = !mHideList.contains(mClock);
} else if (Clock.CLOCK_SECONDS.equals(key)) {
mReceivedSeconds = true;
mHasSeconds = newValue != null && Integer.parseInt(newValue) != 0;
@@ -87,12 +87,12 @@ public class ClockPreference extends DropDownPreference implements TunerService.
Dependency.get(TunerService.class).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1
: 0);
if (DISABLED.equals(value)) {
- mBlacklist.add(mClock);
+ mHideList.add(mClock);
} else {
- mBlacklist.remove(mClock);
+ mHideList.remove(mClock);
}
- Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
- TextUtils.join(",", mBlacklist));
+ Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_HIDE_LIST,
+ TextUtils.join(",", mHideList));
return true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index de8ccfa848e3..cc0050b64d60 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -34,7 +34,7 @@ import java.util.Set;
public class StatusBarSwitch extends SwitchPreference implements Tunable {
- private Set<String> mBlacklist;
+ private Set<String> mHideList;
public StatusBarSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -43,7 +43,7 @@ public class StatusBarSwitch extends SwitchPreference implements Tunable {
@Override
public void onAttached() {
super.onAttached();
- Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_HIDE_LIST);
}
@Override
@@ -54,35 +54,35 @@ public class StatusBarSwitch extends SwitchPreference implements Tunable {
@Override
public void onTuningChanged(String key, String newValue) {
- if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+ if (!StatusBarIconController.ICON_HIDE_LIST.equals(key)) {
return;
}
- mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
- setChecked(!mBlacklist.contains(getKey()));
+ mHideList = StatusBarIconController.getIconHideList(getContext(), newValue);
+ setChecked(!mHideList.contains(getKey()));
}
@Override
protected boolean persistBoolean(boolean value) {
if (!value) {
- // If not enabled add to blacklist.
- if (!mBlacklist.contains(getKey())) {
+ // If not enabled add to hideList.
+ if (!mHideList.contains(getKey())) {
MetricsLogger.action(getContext(), MetricsEvent.TUNER_STATUS_BAR_DISABLE,
getKey());
- mBlacklist.add(getKey());
- setList(mBlacklist);
+ mHideList.add(getKey());
+ setList(mHideList);
}
} else {
- if (mBlacklist.remove(getKey())) {
+ if (mHideList.remove(getKey())) {
MetricsLogger.action(getContext(), MetricsEvent.TUNER_STATUS_BAR_ENABLE, getKey());
- setList(mBlacklist);
+ setList(mHideList);
}
}
return true;
}
- private void setList(Set<String> blacklist) {
+ private void setList(Set<String> hideList) {
ContentResolver contentResolver = getContext().getContentResolver();
- Settings.Secure.putStringForUser(contentResolver, StatusBarIconController.ICON_BLACKLIST,
- TextUtils.join(",", blacklist), ActivityManager.getCurrentUser());
+ Settings.Secure.putStringForUser(contentResolver, StatusBarIconController.ICON_HIDE_LIST,
+ TextUtils.join(",", hideList), ActivityManager.getCurrentUser());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 9ad2aa257aa0..644f7582f146 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -60,7 +60,7 @@ public class TunerServiceImpl extends TunerService {
// Things that use the tunable infrastructure but are now real user settings and
// shouldn't be reset with tuner settings.
- private static final String[] RESET_BLACKLIST = new String[] {
+ private static final String[] RESET_EXCEPTION_LIST = new String[] {
QSTileHost.TILES_SETTING,
Settings.Secure.DOZE_ALWAYS_ON,
Settings.Secure.MEDIA_CONTROLS_RESUME
@@ -116,17 +116,17 @@ public class TunerServiceImpl extends TunerService {
private void upgradeTuner(int oldVersion, int newVersion, Handler mainHandler) {
if (oldVersion < 1) {
- String blacklistStr = getValue(StatusBarIconController.ICON_BLACKLIST);
- if (blacklistStr != null) {
- ArraySet<String> iconBlacklist =
- StatusBarIconController.getIconBlacklist(mContext, blacklistStr);
+ String hideListStr = getValue(StatusBarIconController.ICON_HIDE_LIST);
+ if (hideListStr != null) {
+ ArraySet<String> iconHideList =
+ StatusBarIconController.getIconHideList(mContext, hideListStr);
- iconBlacklist.add("rotate");
- iconBlacklist.add("headset");
+ iconHideList.add("rotate");
+ iconHideList.add("headset");
Settings.Secure.putStringForUser(mContentResolver,
- StatusBarIconController.ICON_BLACKLIST,
- TextUtils.join(",", iconBlacklist), mCurrentUser);
+ StatusBarIconController.ICON_HIDE_LIST,
+ TextUtils.join(",", iconHideList), mCurrentUser);
}
}
if (oldVersion < 2) {
@@ -251,7 +251,7 @@ public class TunerServiceImpl extends TunerService {
mContext.sendBroadcast(intent);
for (String key : mTunableLookup.keySet()) {
- if (ArrayUtils.contains(RESET_BLACKLIST, key)) {
+ if (ArrayUtils.contains(RESET_EXCEPTION_LIST, key)) {
continue;
}
Settings.Secure.putStringForUser(mContentResolver, key, null, user);
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index c63712389a80..551b7b41212a 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -23,7 +23,6 @@ import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
-import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardMessageArea;
import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.dagger.SystemUIRootComponent;
@@ -132,11 +131,6 @@ public class InjectionInflationController {
NotificationShelf creatNotificationShelf();
/**
- * Creates the KeyguardClockSwitch.
- */
- KeyguardClockSwitch createKeyguardClockSwitch();
-
- /**
* Creates the KeyguardSliceView.
*/
KeyguardSliceView createKeyguardSliceView();
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
index b25df5f9c07f..5e7280840bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
@@ -104,9 +104,13 @@ public class LeakReporter {
.setContentText(String.format(
"SystemUI has detected %d leaked objects. Tap to send", garbageCount))
.setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
- .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
+ .setContentIntent(PendingIntent.getActivityAsUser(
+ mContext,
+ 0,
getIntent(hprofFile, dumpFile),
- PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT));
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
+ null,
+ UserHandle.CURRENT));
notiMan.notify(TAG, 0, builder.build());
} catch (IOException e) {
Log.e(TAG, "Couldn't dump heap for leak", e);
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index 9fa03df4229a..06806d0e6ab6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -338,7 +338,7 @@ public class ProximitySensor implements ThresholdSensor {
@Override
public void run() {
unregister();
- mSensor.alertListeners();
+ onProximityEvent(null);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java
index fbc167683a2a..d2c61cc996dd 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java
@@ -21,6 +21,8 @@ import android.os.Handler;
import android.view.IWindowManager;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.pip.phone.PipMenuActivity;
+import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SystemWindows;
@@ -59,9 +61,18 @@ public class WindowManagerShellModule {
@Singleton
@Provides
- static DisplayImeController provideDisplayImeController(
- IWindowManager wmService, DisplayController displayController,
- @Main Handler mainHandler, TransactionPool transactionPool) {
- return new DisplayImeController(wmService, displayController, mainHandler, transactionPool);
+ static DisplayImeController provideDisplayImeController(IWindowManager wmService,
+ DisplayController displayController, @Main Handler mainHandler,
+ TransactionPool transactionPool) {
+ return new DisplayImeController.Builder(wmService, displayController, mainHandler,
+ transactionPool).build();
+ }
+
+ /** TODO(b/150319024): PipMenuActivity will move to a Window */
+ @Singleton
+ @PipMenuActivityClass
+ @Provides
+ static Class<?> providePipMenuActivityClass() {
+ return PipMenuActivity.class;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
new file mode 100644
index 000000000000..657e4fbb4633
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.keyguard;
+
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.verification.VerificationMode;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
+
+ @Mock
+ private StatusBarStateController mStatusBarStateController;
+ @Mock
+ private SysuiColorExtractor mColorExtractor;
+ @Mock
+ private ClockManager mClockManager;
+ @Mock
+ private KeyguardClockSwitch mView;
+ @Mock
+ private ClockPlugin mClockPlugin;
+ @Mock
+ ColorExtractor.GradientColors mGradientColors;
+
+ private KeyguardClockSwitchController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+
+ mController = new KeyguardClockSwitchController(
+ mStatusBarStateController, mColorExtractor, mClockManager);
+
+ when(mView.isAttachedToWindow()).thenReturn(true);
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+ when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
+ }
+
+ @Test
+ public void testAttach_viewAlreadyAttached() {
+ mController.attach(mView);
+
+ verifyAttachment(times(1));
+ }
+
+ @Test
+ public void testAttach_viewNotYetAttached() {
+ ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+
+ when(mView.isAttachedToWindow()).thenReturn(false);
+ mController.attach(mView);
+ verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
+
+ verifyAttachment(never());
+
+ listenerArgumentCaptor.getValue().onViewAttachedToWindow(mView);
+
+ verifyAttachment(times(1));
+ }
+
+
+ @Test
+ public void testAttach_viewDetached() {
+ ArgumentCaptor<View.OnAttachStateChangeListener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+ mController.attach(mView);
+ verify(mView).addOnAttachStateChangeListener(listenerArgumentCaptor.capture());
+
+ verifyAttachment(times(1));
+
+ listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
+
+ verify(mStatusBarStateController).removeCallback(
+ any(StatusBarStateController.StateListener.class));
+ verify(mColorExtractor).removeOnColorsChangedListener(
+ any(ColorExtractor.OnColorsChangedListener.class));
+ }
+
+ @Test
+ public void testBigClockPassesStatusBarState() {
+ ViewGroup testView = new FrameLayout(mContext);
+
+ mController.attach(mView);
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+ mController.setBigClockContainer(testView);
+ verify(mView).setBigClockContainer(testView, StatusBarState.SHADE);
+
+
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
+ mController.setBigClockContainer(testView);
+ verify(mView).setBigClockContainer(testView, StatusBarState.KEYGUARD);
+
+
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
+ mController.setBigClockContainer(testView);
+ verify(mView).setBigClockContainer(testView, StatusBarState.SHADE_LOCKED);
+ }
+
+ @Test
+ public void testPluginPassesStatusBarState() {
+ ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class);
+
+ mController.attach(mView);
+ verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture());
+
+ listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin);
+ verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE);
+ }
+
+ private void verifyAttachment(VerificationMode times) {
+ verify(mClockManager, times).addOnClockChangedListener(
+ any(ClockManager.ClockChangedListener.class));
+ verify(mStatusBarStateController, times).addCallback(
+ any(StatusBarStateController.StateListener.class));
+ verify(mColorExtractor, times).addOnColorsChangedListener(
+ any(ColorExtractor.OnColorsChangedListener.class));
+ verify(mView, times).updateColors(mGradientColors);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 04ceee8b9cea..4c0762e4ea32 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -40,12 +40,10 @@ import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextClock;
-import com.android.keyguard.clock.ClockManager;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ClockPlugin;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.util.InjectionInflationController;
@@ -66,7 +64,6 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
private FrameLayout mClockContainer;
private FrameLayout mBigClockContainer;
private TextClock mBigClock;
- private StatusBarStateController.StateListener mStateListener;
@Mock
TextClock mClockView;
@@ -108,7 +105,6 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
mBigClock = new TextClock(getContext());
MockitoAnnotations.initMocks(this);
when(mClockView.getPaint()).thenReturn(mock(TextPaint.class));
- mStateListener = mKeyguardClockSwitch.getStateListener();
}
@Test
@@ -117,7 +113,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
TextClock pluginView = new TextClock(getContext());
when(plugin.getView()).thenReturn(pluginView);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
verify(mClockView).setVisibility(GONE);
assertThat(plugin.getView().getParent()).isEqualTo(mClockContainer);
@@ -127,14 +123,14 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
public void onPluginConnected_showPluginBigClock() {
// GIVEN that the container for the big clock has visibility GONE
mBigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
// AND in the keyguard state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// THEN the big clock container is visible and it is the parent of the
// big clock view.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
@@ -144,7 +140,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
@Test
public void onPluginConnected_nullView() {
ClockPlugin plugin = mock(ClockPlugin.class);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
verify(mClockView, never()).setVisibility(GONE);
}
@@ -153,11 +149,11 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// GIVEN a plugin has already connected
ClockPlugin plugin1 = mock(ClockPlugin.class);
when(plugin1.getView()).thenReturn(new TextClock(getContext()));
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin1);
+ mKeyguardClockSwitch.setClockPlugin(plugin1, StatusBarState.KEYGUARD);
// WHEN a second plugin is connected
ClockPlugin plugin2 = mock(ClockPlugin.class);
when(plugin2.getView()).thenReturn(new TextClock(getContext()));
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin2);
+ mKeyguardClockSwitch.setClockPlugin(plugin2, StatusBarState.KEYGUARD);
// THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
assertThat(plugin2.getView().getParent()).isEqualTo(mClockContainer);
assertThat(plugin1.getView().getParent()).isNull();
@@ -169,7 +165,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
mKeyguardClockSwitch.setDarkAmount(0.5f);
// WHEN a plugin is connected
ClockPlugin plugin = mock(ClockPlugin.class);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// THEN dark amount should be initalized on the plugin.
verify(plugin).setDarkAmount(0.5f);
}
@@ -181,8 +177,8 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
when(plugin.getView()).thenReturn(pluginView);
mClockView.setVisibility(GONE);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
verify(mClockView).setVisibility(VISIBLE);
assertThat(plugin.getView().getParent()).isNull();
@@ -193,16 +189,16 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// GIVEN that the big clock container is visible
FrameLayout bigClockContainer = new FrameLayout(getContext());
bigClockContainer.setVisibility(VISIBLE);
- mKeyguardClockSwitch.setBigClockContainer(bigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(bigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
when(plugin.getBigClockView()).thenReturn(pluginView);
// AND in the keyguard state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected and then disconnected
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN the big lock container is GONE and the big clock view doesn't have
// a parent.
assertThat(bigClockContainer.getVisibility()).isEqualTo(GONE);
@@ -212,8 +208,8 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
@Test
public void onPluginDisconnected_nullView() {
ClockPlugin plugin = mock(ClockPlugin.class);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
verify(mClockView, never()).setVisibility(GONE);
}
@@ -222,13 +218,12 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// GIVEN two plugins are connected
ClockPlugin plugin1 = mock(ClockPlugin.class);
when(plugin1.getView()).thenReturn(new TextClock(getContext()));
- ClockManager.ClockChangedListener listener = mKeyguardClockSwitch.getClockChangedListener();
- listener.onClockChanged(plugin1);
+ mKeyguardClockSwitch.setClockPlugin(plugin1, StatusBarState.KEYGUARD);
ClockPlugin plugin2 = mock(ClockPlugin.class);
when(plugin2.getView()).thenReturn(new TextClock(getContext()));
- listener.onClockChanged(plugin2);
+ mKeyguardClockSwitch.setClockPlugin(plugin2, StatusBarState.KEYGUARD);
// WHEN the second plugin is disconnected
- listener.onClockChanged(null);
+ mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN the default clock should be shown.
verify(mClockView).setVisibility(VISIBLE);
assertThat(plugin1.getView().getParent()).isNull();
@@ -240,10 +235,9 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// GIVEN a plugin is connected
ClockPlugin clockPlugin = mock(ClockPlugin.class);
when(clockPlugin.getView()).thenReturn(new TextClock(getContext()));
- ClockManager.ClockChangedListener listener = mKeyguardClockSwitch.getClockChangedListener();
- listener.onClockChanged(clockPlugin);
+ mKeyguardClockSwitch.setClockPlugin(clockPlugin, StatusBarState.KEYGUARD);
// WHEN the plugin is disconnected
- listener.onClockChanged(null);
+ mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN onDestroyView is called on the plugin
verify(clockPlugin).onDestroyView();
}
@@ -260,7 +254,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
when(plugin.getView()).thenReturn(pluginView);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setTextColor(Color.WHITE);
@@ -284,7 +278,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
TextClock pluginView = new TextClock(getContext());
when(plugin.getView()).thenReturn(pluginView);
Style style = mock(Style.class);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setStyle(style);
@@ -295,9 +289,9 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
public void onStateChanged_GoneInShade() {
// GIVEN that the big clock container is visible
mBigClockContainer.setVisibility(View.VISIBLE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// WHEN transitioned to SHADE state
- mStateListener.onStateChanged(StatusBarState.SHADE);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.SHADE);
// THEN the container is gone.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
}
@@ -306,13 +300,13 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
public void onStateChanged_VisibleInKeyguard() {
// GIVEN that the big clock container is gone
mBigClockContainer.setVisibility(View.GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND GIVEN that a plugin is active.
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// WHEN transitioned to KEYGUARD state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// THEN the container is visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -324,11 +318,11 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// AND GIVEN that a plugin is active.
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// AND in the keyguard state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the container is associated with the clock switch
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// THEN the container remains visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -340,11 +334,11 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// AND GIVEN that a plugin is active.
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// AND in the keyguard state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the container is associated with the clock switch
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// THEN the container is made visible.
assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -353,14 +347,14 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
public void setKeyguardHidingBigClock_gone() {
// GIVEN that the container for the big clock has visibility GONE
mBigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
// AND in the keyguard state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// WHEN the container set hiding clock as true
mKeyguardClockSwitch.setKeyguardHidingBigClock(true);
// THEN the container is gone.
@@ -371,14 +365,14 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
public void setKeyguardHidingBigClock_visible() {
// GIVEN that the container for the big clock has visibility GONE
mBigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+ mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
// AND the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
// AND in the keyguard state
- mStateListener.onStateChanged(StatusBarState.KEYGUARD);
+ mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
- mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+ mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// WHEN the container set hiding clock as false
mKeyguardClockSwitch.setKeyguardHidingBigClock(false);
// THEN the container is made visible.
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 4a8ada09b3d2..a0e5f73b6a4c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -777,7 +777,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
int subscription = simInited
- ? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE;
+ ? 1/* mock subid=1 */ : SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
if (data != null) intent.putExtras(data);
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subscription);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 71f3d5bee225..ee151c441b68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -32,6 +32,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.view.View;
@@ -61,6 +62,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Mock
private ViewPropertyAnimator mViewPropertyAnimator;
private MagnificationModeSwitch mMagnificationModeSwitch;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -111,6 +113,15 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
}
@Test
+ public void onConfigurationChanged_setImageResource() {
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ mMagnificationModeSwitch.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
+
+ verify(mMockImageView, times(2)).setImageResource(
+ getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
+ }
+
+ @Test
public void performClick_fullscreenMode_removeViewAndChangeSettingsValue() {
ArgumentCaptor<View.OnClickListener> captor = ArgumentCaptor.forClass(
View.OnClickListener.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
index 69482791ef23..9fa5b87af3b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
@@ -16,10 +16,10 @@
package com.android.systemui.accessibility;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import android.content.pm.ActivityInfo;
+import android.hardware.display.DisplayManager;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.view.Display;
@@ -39,8 +39,7 @@ import org.mockito.MockitoAnnotations;
/** Tests the ModeSwitchesController. */
public class ModeSwitchesControllerTest extends SysuiTestCase {
- @Mock
- private ModeSwitchesController.SwitchSupplier mSupplier;
+ private FakeSwitchSupplier mSupplier;
@Mock
private MagnificationModeSwitch mModeSwitch;
private ModeSwitchesController mModeSwitchesController;
@@ -49,7 +48,7 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mSupplier.get(anyInt())).thenReturn(mModeSwitch);
+ mSupplier = new FakeSwitchSupplier(mContext.getSystemService(DisplayManager.class));
mModeSwitchesController = new ModeSwitchesController(mSupplier);
}
@@ -70,4 +69,25 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
verify(mModeSwitch).removeButton();
}
+
+ @Test
+ public void testControllerOnConfigurationChanged_notifyShowingButton() {
+ mModeSwitchesController.showButton(Display.DEFAULT_DISPLAY,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mModeSwitchesController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
+
+ verify(mModeSwitch).onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
+ }
+
+ private class FakeSwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
+
+ FakeSwitchSupplier(DisplayManager displayManager) {
+ super(displayManager);
+ }
+
+ @Override
+ protected MagnificationModeSwitch createInstance(Display display) {
+ return mModeSwitch;
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index 61a2c3f519cb..41360130ac65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -17,10 +17,12 @@
package com.android.systemui.accessibility;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
@@ -96,4 +98,13 @@ public class WindowMagnificationTest extends SysuiTestCase {
verify(connectionCallback).onWindowMagnifierBoundsChanged(Display.DEFAULT_DISPLAY,
testBounds);
}
+
+ @Test
+ public void onConfigurationChanged_updateModeSwitches() {
+ final Configuration config = new Configuration();
+ config.densityDpi = Configuration.DENSITY_DPI_ANY;
+ mWindowMagnification.onConfigurationChanged(config);
+
+ verify(mModeSwitchesController).onConfigurationChanged(anyInt());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 15828b41cc7c..b7589534a770 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -321,7 +321,7 @@ public class BubbleControllerTest extends SysuiTestCase {
Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getEntry().getKey());
assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b));
verify(mNotificationEntryManager, never()).performRemoveNotification(
- eq(mRow.getEntry().getSbn()), anyInt());
+ eq(mRow.getEntry().getSbn()), any(), anyInt());
assertThat(mRow.getEntry().isBubble()).isFalse();
Bubble b2 = mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey());
@@ -352,7 +352,7 @@ public class BubbleControllerTest extends SysuiTestCase {
mBubbleController.removeBubble(
mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
- eq(mRow.getEntry().getSbn()), anyInt());
+ eq(mRow.getEntry().getSbn()), any(), anyInt());
assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
assertFalse(mRow.getEntry().isBubble());
}
@@ -365,7 +365,7 @@ public class BubbleControllerTest extends SysuiTestCase {
mBubbleController.removeBubble(
mRow.getEntry().getKey(), BubbleController.DISMISS_USER_CHANGED);
verify(mNotificationEntryManager, never()).performRemoveNotification(
- eq(mRow.getEntry().getSbn()), anyInt());
+ eq(mRow.getEntry().getSbn()), any(), anyInt());
assertFalse(mBubbleController.hasBubbles());
assertFalse(mSysUiStateBubblesExpanded);
assertTrue(mRow.getEntry().isBubble());
@@ -873,7 +873,7 @@ public class BubbleControllerTest extends SysuiTestCase {
mRow2.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
// Overflow max of 1 is reached; mRow is oldest, so it gets removed
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
- mRow.getEntry().getSbn(), REASON_CANCEL);
+ eq(mRow.getEntry().getSbn()), any(), eq(REASON_CANCEL));
assertEquals(mBubbleData.getBubbles().size(), 1);
assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
}
@@ -985,11 +985,13 @@ public class BubbleControllerTest extends SysuiTestCase {
// THEN only the NON-bubble children are dismissed
List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren();
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
- childrenRows.get(0).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED);
+ eq(childrenRows.get(0).getEntry().getSbn()), any(),
+ eq(REASON_GROUP_SUMMARY_CANCELED));
verify(mNotificationEntryManager, times(1)).performRemoveNotification(
- childrenRows.get(1).getEntry().getSbn(), REASON_GROUP_SUMMARY_CANCELED);
+ eq(childrenRows.get(1).getEntry().getSbn()), any(),
+ eq(REASON_GROUP_SUMMARY_CANCELED));
verify(mNotificationEntryManager, never()).performRemoveNotification(
- eq(groupedBubble.getEntry().getSbn()), anyInt());
+ eq(groupedBubble.getEntry().getSbn()), any(), anyInt());
// THEN the bubble child is suppressed from the shade
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
index 686a09444ee6..43bf19111049 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -301,7 +302,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey()));
// We don't remove the notification since the bubble is still in overflow.
- verify(mNotifCallback, never()).removeNotification(eq(mRow.getEntry()), anyInt());
+ verify(mNotifCallback, never()).removeNotification(eq(mRow.getEntry()), any(), anyInt());
assertFalse(mBubbleController.hasBubbles());
}
@@ -325,7 +326,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
// Since the notif is dismissed and not in overflow, once the bubble is removed,
// removeNotification gets called to really remove the notif
- verify(mNotifCallback, times(1)).removeNotification(eq(mRow.getEntry()), anyInt());
+ verify(mNotifCallback, times(1)).removeNotification(eq(mRow.getEntry()),
+ any(), anyInt());
assertFalse(mBubbleController.hasBubbles());
}
@@ -831,10 +833,11 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
// THEN only the NON-bubble children are dismissed
List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren();
verify(mNotifCallback, times(1)).removeNotification(
- childrenRows.get(0).getEntry(), REASON_GROUP_SUMMARY_CANCELED);
+ eq(childrenRows.get(0).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED));
verify(mNotifCallback, times(1)).removeNotification(
- childrenRows.get(1).getEntry(), REASON_GROUP_SUMMARY_CANCELED);
- verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()), anyInt());
+ eq(childrenRows.get(1).getEntry()), any(), eq(REASON_GROUP_SUMMARY_CANCELED));
+ verify(mNotifCallback, never()).removeNotification(eq(groupedBubble.getEntry()),
+ any(), anyInt());
// THEN the bubble child still exists as a bubble and is suppressed from the shade
assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey()));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
index 71554608f04b..7d8728e4acab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
@@ -94,11 +94,11 @@ public class SeekBarObserverTest : SysuiTestCase() {
@Test
fun seekBarProgress() {
- // WHEN seek bar progress is about half
+ // WHEN part of the track has been played
val data = SeekBarViewModel.Progress(true, true, 3000, 120000)
observer.onChanged(data)
- // THEN seek bar is visible
- assertThat(seekBarView.progress).isEqualTo(100)
+ // THEN seek bar shows the progress
+ assertThat(seekBarView.progress).isEqualTo(3000)
assertThat(seekBarView.max).isEqualTo(120000)
assertThat(elapsedTimeView.getText()).isEqualTo("00:03")
assertThat(totalTimeView.getText()).isEqualTo("02:00")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java
index 583d0692565f..73164b520b9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java
@@ -44,6 +44,7 @@ public class OneHandedAnimationControllerTest extends OneHandedTestCase {
private static final int TEST_BOUNDS_HEIGHT = 1000;
OneHandedAnimationController mOneHandedAnimationController;
+ OneHandedTutorialHandler mTutorialHandler;
@Mock
private SurfaceControl mMockLeash;
@@ -52,6 +53,7 @@ public class OneHandedAnimationControllerTest extends OneHandedTestCase {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mTutorialHandler = new OneHandedTutorialHandler(mContext);
mOneHandedAnimationController = new OneHandedAnimationController(
new OneHandedSurfaceTransactionHelper(mContext));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
index 3231b2852e7c..a989cd1f9c40 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
@@ -61,6 +61,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
DisplayAreaInfo mDisplayAreaInfo;
Display mDisplay;
OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
+ OneHandedTutorialHandler mTutorialHandler;
OneHandedAnimationController.OneHandedTransitionAnimator mFakeAnimator;
WindowContainerToken mToken;
SurfaceControl mLeash;
@@ -97,14 +98,15 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
mMockSurfaceTransactionHelper);
when(mMockAnimator.isRunning()).thenReturn(true);
when(mMockAnimator.setDuration(anyInt())).thenReturn(mFakeAnimator);
- when(mMockAnimator.setOneHandedAnimationCallback(any())).thenReturn(mFakeAnimator);
+ when(mMockAnimator.setOneHandedAnimationCallbacks(any())).thenReturn(mFakeAnimator);
when(mMockAnimator.setTransitionDirection(anyInt())).thenReturn(mFakeAnimator);
when(mMockLeash.getWidth()).thenReturn(DISPLAY_WIDTH);
when(mMockLeash.getHeight()).thenReturn(DISPLAY_HEIGHT);
mDisplayAreaOrganizer = new OneHandedDisplayAreaOrganizer(mContext,
mMockDisplayController,
- mMockAnimationController);
+ mMockAnimationController,
+ mTutorialHandler);
mUpdateHandler = mDisplayAreaOrganizer.getUpdateHandler();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
index 3b284b14c36f..694f51be4e30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
@@ -48,6 +48,7 @@ import org.mockito.MockitoAnnotations;
public class OneHandedGestureHandlerTest extends OneHandedTestCase {
Instrumentation mInstrumentation;
OneHandedTouchHandler mTouchHandler;
+ OneHandedTutorialHandler mTutorialHandler;
OneHandedGestureHandler mGestureHandler;
OneHandedManagerImpl mOneHandedManagerImpl;
@Mock
@@ -62,13 +63,15 @@ public class OneHandedGestureHandlerTest extends OneHandedTestCase {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mInstrumentation = InstrumentationRegistry.getInstrumentation();
- mTouchHandler = Mockito.spy(new OneHandedTouchHandler());
+ mTouchHandler = new OneHandedTouchHandler();
+ mTutorialHandler = new OneHandedTutorialHandler(mContext);
mGestureHandler = Mockito.spy(new OneHandedGestureHandler(
mContext, mMockDisplayController, mMockNavigationModeController));
mOneHandedManagerImpl = new OneHandedManagerImpl(mInstrumentation.getContext(),
mMockDisplayController,
mMockDisplayAreaOrganizer,
mTouchHandler,
+ mTutorialHandler,
mGestureHandler,
mMockSysUiState);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java
index 55bec54eacb8..3418ebf75e0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java
@@ -57,6 +57,8 @@ public class OneHandedManagerImplTest extends OneHandedTestCase {
@Mock
OneHandedTouchHandler mMockTouchHandler;
@Mock
+ OneHandedTutorialHandler mMockTutorialHandler;
+ @Mock
OneHandedGestureHandler mMockGestureHandler;
@Mock
SysUiState mMockSysUiState;
@@ -69,6 +71,7 @@ public class OneHandedManagerImplTest extends OneHandedTestCase {
mMockDisplayController,
mMockDisplayAreaOrganizer,
mMockTouchHandler,
+ mMockTutorialHandler,
mMockGestureHandler,
mMockSysUiState);
mTimeoutHandler = Mockito.spy(OneHandedTimeoutHandler.get());
@@ -84,7 +87,7 @@ public class OneHandedManagerImplTest extends OneHandedTestCase {
final OneHandedAnimationController animationController = new OneHandedAnimationController(
transactionHelper);
OneHandedDisplayAreaOrganizer displayAreaOrganizer = new OneHandedDisplayAreaOrganizer(
- mContext, mMockDisplayController, animationController);
+ mContext, mMockDisplayController, animationController, mMockTutorialHandler);
assertThat(displayAreaOrganizer.isInOneHanded()).isFalse();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
index 3a4ba6a213dc..fdb28d3d43b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
@@ -46,6 +46,7 @@ import org.mockito.MockitoAnnotations;
public class OneHandedTouchHandlerTest extends OneHandedTestCase {
Instrumentation mInstrumentation;
OneHandedTouchHandler mTouchHandler;
+ OneHandedTutorialHandler mTutorialHandler;
OneHandedGestureHandler mGestureHandler;
OneHandedManagerImpl mOneHandedManagerImpl;
@Mock
@@ -68,13 +69,15 @@ public class OneHandedTouchHandlerTest extends OneHandedTestCase {
mMockDisplayController,
mMockDisplayAreaOrganizer,
mTouchHandler,
+ mTutorialHandler,
mGestureHandler,
mMockSysUiState);
}
@Test
public void testOneHandedManager_registerForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer, times(1)).registerTransitionCallback(mTouchHandler);
+ verify(mMockDisplayAreaOrganizer, times(1))
+ .registerTransitionCallback(mTouchHandler);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
new file mode 100644
index 000000000000..f4aa00eaf02f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.systemui.onehanded;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.Instrumentation;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.wm.shell.common.DisplayController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
+ Instrumentation mInstrumentation;
+ OneHandedTouchHandler mTouchHandler;
+ OneHandedTutorialHandler mTutorialHandler;
+ OneHandedGestureHandler mGestureHandler;
+ OneHandedManagerImpl mOneHandedManagerImpl;
+ @Mock
+ DisplayController mMockDisplayController;
+ @Mock
+ NavigationModeController mMockNavigationModeController;
+ @Mock
+ OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
+ @Mock
+ SysUiState mMockSysUiState;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mTouchHandler = new OneHandedTouchHandler();
+ mTutorialHandler = Mockito.spy(new OneHandedTutorialHandler(mContext));
+ mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController,
+ mMockNavigationModeController);
+ mOneHandedManagerImpl = new OneHandedManagerImpl(mInstrumentation.getContext(),
+ mMockDisplayController,
+ mMockDisplayAreaOrganizer,
+ mTouchHandler,
+ mTutorialHandler,
+ mGestureHandler,
+ mMockSysUiState);
+ }
+
+ @Test
+ public void testOneHandedManager_registerForDisplayAreaOrganizer() {
+ verify(mMockDisplayAreaOrganizer, times(1))
+ .registerTransitionCallback(mTutorialHandler);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java
index c9c111198f4c..f0066ba4f66a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java
@@ -16,7 +16,7 @@
package com.android.systemui.pip;
-import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
+import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
import static org.junit.Assert.assertEquals;
@@ -116,9 +116,9 @@ public class PipAnimationControllerTest extends SysuiTestCase {
animator = mPipAnimationController
.getAnimator(mLeash, new Rect(), 0f, 1f)
- .setTransitionDirection(TRANSITION_DIRECTION_TO_FULLSCREEN);
+ .setTransitionDirection(TRANSITION_DIRECTION_LEAVE_PIP);
assertEquals("Transition to fullscreen mode",
- animator.getTransitionDirection(), TRANSITION_DIRECTION_TO_FULLSCREEN);
+ animator.getTransitionDirection(), TRANSITION_DIRECTION_LEAVE_PIP);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 4fd5d057c003..6f46923cda5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -55,7 +55,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationListItem;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -293,15 +292,9 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
public void notifyGroupChildAdded(ExpandableView row) {}
@Override
- public void notifyGroupChildAdded(View v) {}
-
- @Override
public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {}
@Override
- public void notifyGroupChildRemoved(View v, ViewGroup childrenContainer) {}
-
- @Override
public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {}
@Override
@@ -327,11 +320,6 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
}
@Override
- public void removeListItem(NotificationListItem li) {
- removeContainerView(li.getView());
- }
-
- @Override
public void setNotificationActivityStarter(
NotificationActivityStarter notificationActivityStarter) {}
@@ -342,8 +330,9 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
}
@Override
- public void addListItem(NotificationListItem li) {
- addContainerView(li.getView());
+ public void addContainerViewAt(View v, int index) {
+ mLayout.addView(v, index);
+ mRows.add(index, v);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
index 619d2444b4dd..fb8c3d9af05c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
@@ -57,8 +57,8 @@ public class AssistantFeedbackControllerTest extends SysuiTestCase {
@Before
public void setUp() {
- switchSetting(ON);
mAssistantFeedbackController = new AssistantFeedbackController(mContext);
+ switchSetting(ON);
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, TEST_UID, 0, new Notification(),
UserHandle.CURRENT, null, 0);
@@ -72,7 +72,6 @@ public class AssistantFeedbackControllerTest extends SysuiTestCase {
@Test
public void testUserControls_settingEnabled() {
- switchSetting(ON);
assertTrue(mAssistantFeedbackController.isFeedbackEnabled());
}
@@ -113,7 +112,8 @@ public class AssistantFeedbackControllerTest extends SysuiTestCase {
}
private void switchSetting(int setting) {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.NOTIFICATION_FEEDBACK_ENABLED, setting, UserHandle.USER_CURRENT);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.NOTIFICATION_FEEDBACK_ENABLED, setting);
+ mAssistantFeedbackController.update(null);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 8a49326add25..d4718e7e55fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -57,11 +57,11 @@ import android.util.ArraySet;
import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -75,6 +75,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
+import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -202,8 +203,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
() -> mRemoteInputManager,
mLeakDetector,
mock(ForegroundServiceDismissalFeatureController.class),
- mock(HeadsUpManager.class),
- mock(StatusBarStateController.class)
+ mock(IStatusBarService.class)
);
mEntryManager.setUpWithPresenter(mPresenter);
mEntryManager.addNotificationEntryListener(mEntryListener);
@@ -294,7 +294,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
assertTrue(entriesContainKey(mEntryManager.getAllNotifs(), mSbn.getKey()));
// WHEN the uninflated entry is removed
- mEntryManager.performRemoveNotification(mSbn, UNDEFINED_DISMISS_REASON);
+ mEntryManager.performRemoveNotification(mSbn, mock(DismissedByUserStats.class),
+ UNDEFINED_DISMISS_REASON);
// THEN the entry is still removed from the allNotifications list
assertFalse(entriesContainKey(mEntryManager.getAllNotifs(), mSbn.getKey()));
@@ -470,7 +471,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
@Test
public void testPerformRemoveNotification_removedEntry() {
mEntryManager.removeNotification(mSbn.getKey(), null, 0);
- mEntryManager.performRemoveNotification(mSbn, REASON_CANCEL);
+ mEntryManager.performRemoveNotification(mSbn, mock(DismissedByUserStats.class),
+ REASON_CANCEL);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index 37561c4e33ed..bec5174aceba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -41,13 +41,13 @@ import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotifViewBarn;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 601df2cb4fc7..a90af87064b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -40,6 +40,7 @@ import android.testing.TestableLooper;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import androidx.test.filters.SmallTest;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -185,8 +186,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
() -> mRemoteInputManager,
mLeakDetector,
mock(ForegroundServiceDismissalFeatureController.class),
- mock(HeadsUpManager.class),
- mock(StatusBarStateController.class)
+ mock(IStatusBarService.class)
);
NotifRemoteViewCache cache = new NotifRemoteViewCacheImpl(mEntryManager);
@@ -252,7 +252,6 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
mLockscreenUserManager,
pipeline,
mRowContentBindStage,
- mNotificationInterruptionStateProvider,
RowInflaterTask::new,
mExpandableNotificationRowComponentBuilder,
new IconManager(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 6d411333b220..ddac2ecbd6eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -49,13 +49,13 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -93,7 +93,6 @@ import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.leak.LeakDetector;
@@ -193,8 +192,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
() -> mRemoteInputManager,
mock(LeakDetector.class),
mock(ForegroundServiceDismissalFeatureController.class),
- mock(HeadsUpManager.class),
- mock(StatusBarStateController.class)
+ mock(IStatusBarService.class)
);
mEntryManager.setUpWithPresenter(mock(NotificationPresenter.class));
when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index a927c8011b8f..64907eef2dd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -136,6 +136,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
anyFloat());
assertThat(mBiometricUnlockController.getMode())
.isEqualTo(BiometricUnlockController.MODE_SHOW_BOUNCER);
+ assertThat(mBiometricUnlockController.getBiometricType())
+ .isEqualTo(BiometricSourceType.FINGERPRINT);
}
@Test
@@ -268,6 +270,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
assertThat(mBiometricUnlockController.getMode())
.isEqualTo(BiometricUnlockController.MODE_DISMISS_BOUNCER);
+ assertThat(mBiometricUnlockController.getBiometricType())
+ .isEqualTo(BiometricSourceType.FACE);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index b0b66b87d421..c7434f6fd95f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -51,6 +51,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitch;
+import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -183,6 +184,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private BiometricUnlockController mBiometricUnlockController;
@Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ @Mock
+ private KeyguardClockSwitchController mKeyguardClockSwitchController;
private FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -240,7 +243,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mMetricsLogger, mActivityManager, mZenModeController, mConfigurationController,
mFlingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
mConversationNotificationManager, mMediaHiearchyManager,
- mBiometricUnlockController, mStatusBarKeyguardViewManager);
+ mBiometricUnlockController, mStatusBarKeyguardViewManager,
+ () -> mKeyguardClockSwitchController);
mNotificationPanelViewController.initDependencies(mStatusBar, mGroupManager,
mNotificationShelf, mNotificationAreaController, mScrimController);
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index acdb2c59dc0c..33067343ba40 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -73,6 +73,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.row.OnDismissCallback;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -131,6 +132,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
@Mock
private Intent mContentIntentInner;
@Mock
+ private OnDismissCallback mOnDismissCallback;
+ @Mock
private NotificationActivityStarter mNotificationActivityStarter;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -207,7 +210,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mFeatureFlags,
mock(MetricsLogger.class),
- mock(StatusBarNotificationActivityStarterLogger.class))
+ mock(StatusBarNotificationActivityStarterLogger.class),
+ mOnDismissCallback)
.setStatusBar(mStatusBar)
.setNotificationPresenter(mock(NotificationPresenter.class))
.setNotificationPanelViewController(mock(NotificationPanelViewController.class))
@@ -266,8 +270,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mClickNotifier).onNotificationClick(
eq(sbn.getKey()), any(NotificationVisibility.class));
- // Notification is removed due to FLAG_AUTO_CANCEL
- verify(mEntryManager).performRemoveNotification(eq(sbn), eq(REASON_CLICK));
+ // Notification calls dismiss callback to remove notification due to FLAG_AUTO_CANCEL
+ verify(mOnDismissCallback).onDismiss(mNotificationRow.getEntry(), REASON_CLICK);
}
@Test
@@ -296,7 +300,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verifyZeroInteractions(mContentIntent);
// Notification should not be cancelled.
- verify(mEntryManager, never()).performRemoveNotification(eq(sbn), anyInt());
+ verify(mOnDismissCallback, never()).onDismiss(eq(mNotificationRow.getEntry()), anyInt());
}
@Test
@@ -326,7 +330,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verifyZeroInteractions(mContentIntent);
// Notification should not be cancelled.
- verify(mEntryManager, never()).performRemoveNotification(eq(sbn), anyInt());
+ verify(mEntryManager, never()).performRemoveNotification(eq(sbn), any(), anyInt());
}
@Test
@@ -358,6 +362,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verifyNoMoreInteractions(mContentIntent);
// Notification should not be cancelled.
- verify(mEntryManager, never()).performRemoveNotification(eq(sbn), anyInt());
+ verify(mEntryManager, never()).performRemoveNotification(eq(sbn), any(), anyInt());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
index 8ba11dae2b5c..c5a197eef2d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.util.sensors;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -80,6 +81,8 @@ public class ProximityCheckTest extends SysuiTestCase {
mFakeExecutor.runAllReady();
assertFalse(mFakeProximitySensor.isRegistered());
+ assertEquals(1, mTestableCallback.mNumCalls);
+ assertNull(mTestableCallback.mLastResult);
}
@Test
@@ -110,9 +113,12 @@ public class ProximityCheckTest extends SysuiTestCase {
private static class TestableCallback implements Consumer<Boolean> {
Boolean mLastResult;
+ int mNumCalls = 0;
+
@Override
public void accept(Boolean result) {
mLastResult = result;
+ mNumCalls++;
}
}
}
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index a8cd63d90676..915c2f6087b8 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -32,6 +32,7 @@ java_defaults {
"android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"net-utils-framework-common",
+ "net-utils-device-common",
],
libs: [
"framework-statsd.stubs.module_lib",
diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml
index 2b2fe4534c3e..e6444f3ead5c 100644
--- a/packages/Tethering/AndroidManifest.xml
+++ b/packages/Tethering/AndroidManifest.xml
@@ -24,7 +24,7 @@
<!-- Permissions must be defined here, and not in the base manifest, as the tethering
running in the system server process does not need any permission, and having
privileged permissions added would cause crashes on startup unless they are also
- added to the privileged permissions whitelist for that package. -->
+ added to the privileged permissions allowlist for that package. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
diff --git a/packages/Tethering/proguard.flags b/packages/Tethering/proguard.flags
index 051fbd19fc6c..86b903353cf5 100644
--- a/packages/Tethering/proguard.flags
+++ b/packages/Tethering/proguard.flags
@@ -1,5 +1,5 @@
# Keep class's integer static field for MessageUtils to parsing their name.
--keep class com.android.networkstack.tethering.Tethering$TetherMasterSM {
+-keep class com.android.networkstack.tethering.Tethering$TetherMainSM {
static final int CMD_*;
static final int EVENT_*;
}
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 9131317e8d70..673cbf09d259 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -197,15 +197,19 @@ public class IpServer extends StateMachine {
public static final int CMD_TETHER_UNREQUESTED = BASE_IPSERVER + 2;
// notification that this interface is down
public static final int CMD_INTERFACE_DOWN = BASE_IPSERVER + 3;
- // notification from the master SM that it had trouble enabling IP Forwarding
+ // notification from the {@link Tethering.TetherMainSM} that it had trouble enabling IP
+ // Forwarding
public static final int CMD_IP_FORWARDING_ENABLE_ERROR = BASE_IPSERVER + 4;
- // notification from the master SM that it had trouble disabling IP Forwarding
+ // notification from the {@link Tethering.TetherMainSM} SM that it had trouble disabling IP
+ // Forwarding
public static final int CMD_IP_FORWARDING_DISABLE_ERROR = BASE_IPSERVER + 5;
- // notification from the master SM that it had trouble starting tethering
+ // notification from the {@link Tethering.TetherMainSM} SM that it had trouble starting
+ // tethering
public static final int CMD_START_TETHERING_ERROR = BASE_IPSERVER + 6;
- // notification from the master SM that it had trouble stopping tethering
+ // notification from the {@link Tethering.TetherMainSM} that it had trouble stopping tethering
public static final int CMD_STOP_TETHERING_ERROR = BASE_IPSERVER + 7;
- // notification from the master SM that it had trouble setting the DNS forwarders
+ // notification from the {@link Tethering.TetherMainSM} that it had trouble setting the DNS
+ // forwarders
public static final int CMD_SET_DNS_FORWARDERS_ERROR = BASE_IPSERVER + 8;
// the upstream connection has changed
public static final int CMD_TETHER_CONNECTION_CHANGED = BASE_IPSERVER + 9;
@@ -1320,7 +1324,7 @@ public class IpServer extends StateMachine {
/**
* This state is terminal for the per interface state machine. At this
- * point, the master state machine should have removed this interface
+ * point, the tethering main state machine should have removed this interface
* specific state machine from its list of possible recipients of
* tethering requests. The state machine itself will hang around until
* the garbage collector finds it.
diff --git a/packages/Tethering/src/android/net/util/TetheringMessageBase.java b/packages/Tethering/src/android/net/util/TetheringMessageBase.java
index 1b763ce920da..29c0a817b6f4 100644
--- a/packages/Tethering/src/android/net/util/TetheringMessageBase.java
+++ b/packages/Tethering/src/android/net/util/TetheringMessageBase.java
@@ -19,7 +19,7 @@ package android.net.util;
* This class defines Message.what base addresses for various state machine.
*/
public class TetheringMessageBase {
- public static final int BASE_MASTER = 0;
+ public static final int BASE_MAIN_SM = 0;
public static final int BASE_IPSERVER = 100;
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
index 9dace709d734..bb7322f2a0d2 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
@@ -296,16 +296,16 @@ public class EntitlementManager {
* Reference TetheringManager.TETHERING_{@code *} for each tether type.
*
* @param config an object that encapsulates the various tethering configuration elements.
- * Note: this method is only called from TetherMaster on the handler thread.
+ * Note: this method is only called from @{link Tethering.TetherMainSM} on the handler thread.
* If there are new callers from different threads, the logic should move to
- * masterHandler to avoid race conditions.
+ * @{link Tethering.TetherMainSM} handler to avoid race conditions.
*/
public void reevaluateSimCardProvisioning(final TetheringConfiguration config) {
if (DBG) mLog.i("reevaluateSimCardProvisioning");
if (!mHandler.getLooper().isCurrentThread()) {
// Except for test, this log should not appear in normal flow.
- mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
+ mLog.log("reevaluateSimCardProvisioning() don't run in TetherMainSM thread");
}
mEntitlementCacheValue.clear();
mCurrentEntitlementResults.clear();
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 7508a653599d..cfc657587332 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -50,7 +50,7 @@ import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
-import static android.net.util.TetheringMessageBase.BASE_MASTER;
+import static android.net.util.TetheringMessageBase.BASE_MAIN_SM;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -159,7 +159,7 @@ public class Tethering {
private static final boolean VDBG = false;
private static final Class[] sMessageClasses = {
- Tethering.class, TetherMasterSM.class, IpServer.class
+ Tethering.class, TetherMainSM.class, IpServer.class
};
private static final SparseArray<String> sMagicDecoderRing =
MessageUtils.findMessageNames(sMessageClasses);
@@ -216,7 +216,7 @@ public class Tethering {
private final ArrayMap<String, TetherState> mTetherStates;
private final BroadcastReceiver mStateReceiver;
private final Looper mLooper;
- private final StateMachine mTetherMasterSM;
+ private final StateMachine mTetherMainSM;
private final OffloadController mOffloadController;
private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
// TODO: Figure out how to merge this and other downstream-tracking objects
@@ -273,10 +273,10 @@ public class Tethering {
mTetherStates = new ArrayMap<>();
mConnectedClientsTracker = new ConnectedClientsTracker();
- mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
- mTetherMasterSM.start();
+ mTetherMainSM = new TetherMainSM("TetherMain", mLooper, deps);
+ mTetherMainSM.start();
- mHandler = mTetherMasterSM.getHandler();
+ mHandler = mTetherMainSM.getHandler();
mOffloadController = mDeps.getOffloadController(mHandler, mLog,
new OffloadController.Dependencies() {
@@ -285,8 +285,8 @@ public class Tethering {
return mConfig;
}
});
- mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
- TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
+ mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMainSM, mLog,
+ TetherMainSM.EVENT_UPSTREAM_CALLBACK);
mForwardedDownstreams = new LinkedHashSet<>();
IntentFilter filter = new IntentFilter();
@@ -294,8 +294,8 @@ public class Tethering {
// EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
// permission is changed according to entitlement check result.
mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
- () -> mTetherMasterSM.sendMessage(
- TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
+ () -> mTetherMainSM.sendMessage(
+ TetherMainSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
mLog.log("OBSERVED UiEnitlementFailed");
stopTethering(downstream);
@@ -945,7 +945,7 @@ public class Tethering {
}
if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
+ mTetherMainSM.sendMessage(TetherMainSM.CMD_UPSTREAM_CHANGED);
}
private void handleUsbAction(Intent intent) {
@@ -1170,7 +1170,7 @@ public class Tethering {
private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
if (TextUtils.isEmpty(ifname)) return;
- disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
+ disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* fake */ 0);
}
private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
@@ -1381,23 +1381,23 @@ public class Tethering {
return false;
}
- class TetherMasterSM extends StateMachine {
+ class TetherMainSM extends StateMachine {
// an interface SM has requested Tethering/Local Hotspot
- static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
+ static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MAIN_SM + 1;
// an interface SM has unrequested Tethering/Local Hotspot
- static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2;
+ static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MAIN_SM + 2;
// upstream connection change - do the right thing
- static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3;
+ static final int CMD_UPSTREAM_CHANGED = BASE_MAIN_SM + 3;
// we don't have a valid upstream conn, check again after a delay
- static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4;
- // Events from NetworkCallbacks that we process on the master state
+ static final int CMD_RETRY_UPSTREAM = BASE_MAIN_SM + 4;
+ // Events from NetworkCallbacks that we process on the main state
// machine thread on behalf of the UpstreamNetworkMonitor.
- static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
+ static final int EVENT_UPSTREAM_CALLBACK = BASE_MAIN_SM + 5;
// we treated the error and want now to clear it
- static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
- static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
+ static final int CMD_CLEAR_ERROR = BASE_MAIN_SM + 6;
+ static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MAIN_SM + 7;
// Events from EntitlementManager to choose upstream again.
- static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8;
+ static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MAIN_SM + 8;
private final State mInitialState;
private final State mTetherModeAliveState;
@@ -1425,7 +1425,7 @@ public class Tethering {
private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
- TetherMasterSM(String name, Looper looper, TetheringDependencies deps) {
+ TetherMainSM(String name, Looper looper, TetheringDependencies deps) {
super(name, looper);
mInitialState = new InitialState();
@@ -1479,7 +1479,7 @@ public class Tethering {
}
}
- protected boolean turnOnMasterTetherSettings() {
+ protected boolean turnOnMainTetherSettings() {
final TetheringConfiguration cfg = mConfig;
try {
mNetd.ipfwdEnableForwarding(TAG);
@@ -1506,11 +1506,11 @@ public class Tethering {
return false;
}
}
- mLog.log("SET master tether settings: ON");
+ mLog.log("SET main tether settings: ON");
return true;
}
- protected boolean turnOffMasterTetherSettings() {
+ protected boolean turnOffMainTetherSettings() {
try {
mNetd.tetherStop();
} catch (RemoteException | ServiceSpecificException e) {
@@ -1526,7 +1526,7 @@ public class Tethering {
return false;
}
transitionTo(mInitialState);
- mLog.log("SET master tether settings: OFF");
+ mLog.log("SET main tether settings: OFF");
return true;
}
@@ -1730,7 +1730,7 @@ public class Tethering {
// TODO: Re-evaluate possible upstreams. Currently upstream
// reevaluation is triggered via received CONNECTIVITY_ACTION
// broadcasts that result in being passed a
- // TetherMasterSM.CMD_UPSTREAM_CHANGED.
+ // TetherMainSM.CMD_UPSTREAM_CHANGED.
handleNewUpstreamNetworkState(null);
break;
default:
@@ -1745,9 +1745,9 @@ public class Tethering {
@Override
public void enter() {
- // If turning on master tether settings fails, we have already
+ // If turning on main tether settings fails, we have already
// transitioned to an error state; exit early.
- if (!turnOnMasterTetherSettings()) {
+ if (!turnOnMainTetherSettings()) {
return;
}
@@ -1819,7 +1819,7 @@ public class Tethering {
if (mNotifyList.isEmpty()) {
// This transitions us out of TetherModeAliveState,
// either to InitialState or an error state.
- turnOffMasterTetherSettings();
+ turnOffMainTetherSettings();
break;
}
@@ -2329,7 +2329,7 @@ public class Tethering {
};
}
- // TODO: Move into TetherMasterSM.
+ // TODO: Move into TetherMainSM.
private void notifyInterfaceStateChange(IpServer who, int state, int error) {
final String iface = who.interfaceName();
synchronized (mPublicSync) {
@@ -2344,27 +2344,27 @@ public class Tethering {
mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
- // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
- // Thus we give a chance for TetherMasterSM to recover to InitialState
+ // If TetherMainSM is in ErrorState, TetherMainSM stays there.
+ // Thus we give a chance for TetherMainSM to recover to InitialState
// by sending CMD_CLEAR_ERROR
if (error == TETHER_ERROR_INTERNAL_ERROR) {
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
+ mTetherMainSM.sendMessage(TetherMainSM.CMD_CLEAR_ERROR, who);
}
int which;
switch (state) {
case IpServer.STATE_UNAVAILABLE:
case IpServer.STATE_AVAILABLE:
- which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
+ which = TetherMainSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
break;
case IpServer.STATE_TETHERED:
case IpServer.STATE_LOCAL_ONLY:
- which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
+ which = TetherMainSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
break;
default:
Log.wtf(TAG, "Unknown interface state: " + state);
return;
}
- mTetherMasterSM.sendMessage(which, state, 0, who);
+ mTetherMainSM.sendMessage(which, state, 0, who);
sendTetherStateChangedBroadcast();
}
@@ -2384,8 +2384,8 @@ public class Tethering {
mLog.log(String.format(
"OBSERVED LinkProperties update iface=%s state=%s lp=%s",
iface, IpServer.getStateString(state), newLp));
- final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
- mTetherMasterSM.sendMessage(which, state, 0, newLp);
+ final int which = TetherMainSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
+ mTetherMainSM.sendMessage(which, state, 0, newLp);
}
private void maybeTrackNewInterfaceLocked(final String iface) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index 320427c393ac..b17065cb7804 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -63,7 +63,7 @@ import java.util.Set;
* Calling #registerMobileNetworkRequest() to bring up mobile DUN/HIPRI network.
*
* The methods and data members of this class are only to be accessed and
- * modified from the tethering master state machine thread. Any other
+ * modified from the tethering main state machine thread. Any other
* access semantics would necessitate the addition of locking.
*
* TODO: Move upstream selection logic here.
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 1b710d00d0c7..46fe5cf093fd 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -337,11 +337,11 @@ public class TetheringTest {
}
public class MockTetheringDependencies extends TetheringDependencies {
- StateMachine mUpstreamNetworkMonitorMasterSM;
+ StateMachine mUpstreamNetworkMonitorSM;
ArrayList<IpServer> mIpv6CoordinatorNotifyList;
public void reset() {
- mUpstreamNetworkMonitorMasterSM = null;
+ mUpstreamNetworkMonitorSM = null;
mIpv6CoordinatorNotifyList = null;
}
@@ -368,7 +368,7 @@ public class TetheringTest {
@Override
public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
StateMachine target, SharedLog log, int what) {
- mUpstreamNetworkMonitorMasterSM = target;
+ mUpstreamNetworkMonitorSM = target;
return mUpstreamNetworkMonitor;
}
@@ -911,8 +911,8 @@ public class TetheringTest {
initTetheringUpstream(upstreamState);
// Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
- Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+ mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
+ Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
0,
upstreamState);
@@ -1126,7 +1126,7 @@ public class TetheringTest {
verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
// This never gets called because of the exception thrown above.
verify(mNetd, times(0)).tetherStartWithConfiguration(any());
- // When the master state machine transitions to an error state it tells
+ // When the main state machine transitions to an error state it tells
// downstream interfaces, which causes us to tell Wi-Fi about the error
// so it can take down AP mode.
verify(mNetd, times(1)).tetherApplyDnsInterfaces();
@@ -1753,8 +1753,8 @@ public class TetheringTest {
@Test
public void testUpstreamNetworkChanged() {
- final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
+ final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
+ mTetheringDependencies.mUpstreamNetworkMonitorSM;
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true);
@@ -1765,8 +1765,8 @@ public class TetheringTest {
@Test
public void testUpstreamCapabilitiesChanged() {
- final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
+ final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
+ mTetheringDependencies.mUpstreamNetworkMonitorSM;
final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
initTetheringUpstream(upstreamState);
stateMachine.chooseUpstreamType(true);
@@ -1891,8 +1891,8 @@ public class TetheringTest {
any(), any());
reset(mNetd, mUsbManager);
upstreamNetwork = buildV4WifiUpstreamState(ipv4Address, 30, wifiNetwork);
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
- Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+ mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
+ Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
0,
upstreamNetwork);
@@ -1929,8 +1929,8 @@ public class TetheringTest {
final UpstreamNetworkState upstreamNetwork = buildV4WifiUpstreamState(
upstreamAddress, 16, wifiNetwork);
- mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
- Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+ mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
+ Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
0,
upstreamNetwork);
diff --git a/services/Android.bp b/services/Android.bp
index f0144ac1c695..ef52c2aff002 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -30,6 +30,7 @@ filegroup {
":services.midi-sources",
":services.net-sources",
":services.print-sources",
+ ":services.profcollect-sources",
":services.restrictions-sources",
":services.startop.iorap-sources",
":services.systemcaptions-sources",
@@ -73,6 +74,7 @@ java_library {
"services.net",
"services.people",
"services.print",
+ "services.profcollect",
"services.restrictions",
"services.startop",
"services.systemcaptions",
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index 44c4bf4836a0..b6f2a47dd5e2 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -16,8 +16,10 @@
package com.android.server.accessibility.magnification;
+import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -61,6 +63,8 @@ public class FullScreenMagnificationController {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "FullScreenMagnificationController";
+ private static final Runnable STUB_RUNNABLE = () -> {
+ };
public static final float MIN_SCALE = 1.0f;
public static final float MAX_SCALE = 8.0f;
@@ -292,7 +296,7 @@ public class FullScreenMagnificationController {
// Adjust the current spec's offsets if necessary.
if (updateCurrentSpecWithOffsetsLocked(
mCurrentMagnificationSpec.offsetX, mCurrentMagnificationSpec.offsetY)) {
- sendSpecToAnimation(mCurrentMagnificationSpec, false);
+ sendSpecToAnimation(mCurrentMagnificationSpec, null);
}
onMagnificationChangedLocked();
}
@@ -300,17 +304,18 @@ public class FullScreenMagnificationController {
}
}
- void sendSpecToAnimation(MagnificationSpec spec, boolean animate) {
+ void sendSpecToAnimation(MagnificationSpec spec, Runnable endCallback) {
if (DEBUG) {
Slog.i(LOG_TAG,
- "sendSpecToAnimation(spec = " + spec + ", animate = " + animate + ")");
+ "sendSpecToAnimation(spec = " + spec + ", endCallback = " + endCallback
+ + ")");
}
if (Thread.currentThread().getId() == mMainThreadId) {
- mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
+ mSpecAnimationBridge.updateSentSpecMainThread(spec, endCallback);
} else {
final Message m = PooledLambda.obtainMessage(
SpecAnimationBridge::updateSentSpecMainThread,
- mSpecAnimationBridge, spec, animate);
+ mSpecAnimationBridge, spec, endCallback);
mControllerCtx.getHandler().sendMessage(m);
}
}
@@ -410,6 +415,11 @@ public class FullScreenMagnificationController {
@GuardedBy("mLock")
boolean reset(boolean animate) {
+ return reset(transformToStubRunnable(animate));
+ }
+
+ @GuardedBy("mLock")
+ boolean reset(Runnable endCallback) {
if (!mRegistered) {
return false;
}
@@ -420,7 +430,7 @@ public class FullScreenMagnificationController {
onMagnificationChangedLocked();
}
mIdOfLastServiceToMagnify = INVALID_ID;
- sendSpecToAnimation(spec, animate);
+ sendSpecToAnimation(spec, endCallback);
return changed;
}
@@ -448,24 +458,24 @@ public class FullScreenMagnificationController {
final float centerX = normPivotX + offsetX;
final float centerY = normPivotY + offsetY;
mIdOfLastServiceToMagnify = id;
- return setScaleAndCenter(scale, centerX, centerY, animate, id);
+ return setScaleAndCenter(scale, centerX, centerY, transformToStubRunnable(animate), id);
}
@GuardedBy("mLock")
boolean setScaleAndCenter(float scale, float centerX, float centerY,
- boolean animate, int id) {
+ Runnable endCallback, int id) {
if (!mRegistered) {
return false;
}
if (DEBUG) {
Slog.i(LOG_TAG,
"setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
- + ", centerY = " + centerY + ", animate = " + animate
+ + ", centerY = " + centerY + ", endCallback = " + endCallback
+ ", id = " + id
+ ")");
}
final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
- sendSpecToAnimation(mCurrentMagnificationSpec, animate);
+ sendSpecToAnimation(mCurrentMagnificationSpec, endCallback);
if (isMagnifying() && (id != INVALID_ID)) {
mIdOfLastServiceToMagnify = id;
}
@@ -531,7 +541,7 @@ public class FullScreenMagnificationController {
if (id != INVALID_ID) {
mIdOfLastServiceToMagnify = id;
}
- sendSpecToAnimation(mCurrentMagnificationSpec, false);
+ sendSpecToAnimation(mCurrentMagnificationSpec, null);
}
boolean updateCurrentSpecWithOffsetsLocked(float nonNormOffsetX, float nonNormOffsetY) {
@@ -865,12 +875,26 @@ public class FullScreenMagnificationController {
* the spec did not change
*/
public boolean reset(int displayId, boolean animate) {
+ return reset(displayId, animate ? STUB_RUNNABLE : null);
+ }
+
+ /**
+ * Resets the magnification scale and center, optionally animating the
+ * transition.
+ *
+ * @param displayId The logical display id.
+ * @param endCallback Called when the animation is ended or the spec did not change.
+ * {@code null} to transition immediately
+ * @return {@code true} if the magnification spec changed, {@code false} if
+ * the spec did not change
+ */
+ public boolean reset(int displayId, Runnable endCallback) {
synchronized (mLock) {
final DisplayMagnification display = mDisplays.get(displayId);
if (display == null) {
return false;
}
- return display.reset(animate);
+ return display.reset(endCallback);
}
}
@@ -921,7 +945,8 @@ public class FullScreenMagnificationController {
if (display == null) {
return false;
}
- return display.setScaleAndCenter(Float.NaN, centerX, centerY, animate, id);
+ return display.setScaleAndCenter(Float.NaN, centerX, centerY,
+ animate ? STUB_RUNNABLE : null, id);
}
}
@@ -944,12 +969,35 @@ public class FullScreenMagnificationController {
*/
public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY,
boolean animate, int id) {
+ return setScaleAndCenter(displayId, scale, centerX, centerY,
+ transformToStubRunnable(animate), id);
+ }
+
+ /**
+ * Sets the scale and center of the magnified region, optionally
+ * animating the transition. If animation is disabled, the transition
+ * is immediate.
+ *
+ * @param displayId The logical display id.
+ * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+ * @param centerX the screen-relative X coordinate around which to
+ * center and scale, or {@link Float#NaN} to leave unchanged
+ * @param centerY the screen-relative Y coordinate around which to
+ * center and scale, or {@link Float#NaN} to leave unchanged
+ * @param endCallback called when the transition is finished successfully or the spec did not
+ * change. {@code null} to transition immediately.
+ * @param id the ID of the service requesting the change
+ * @return {@code true} if the magnification spec changed, {@code false} if
+ * the spec did not change
+ */
+ public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY,
+ Runnable endCallback, int id) {
synchronized (mLock) {
final DisplayMagnification display = mDisplays.get(displayId);
if (display == null) {
return false;
}
- return display.setScaleAndCenter(scale, centerX, centerY, animate, id);
+ return display.setScaleAndCenter(scale, centerX, centerY, endCallback, id);
}
}
@@ -1160,7 +1208,8 @@ public class FullScreenMagnificationController {
* Class responsible for animating spec on the main thread and sending spec
* updates to the window manager.
*/
- private static class SpecAnimationBridge implements ValueAnimator.AnimatorUpdateListener {
+ private static class SpecAnimationBridge implements ValueAnimator.AnimatorUpdateListener,
+ Animator.AnimatorListener {
private final ControllerContext mControllerCtx;
/**
@@ -1180,6 +1229,8 @@ public class FullScreenMagnificationController {
*/
private final ValueAnimator mValueAnimator;
+ // Called when the callee wants animating and the sent spec matches the target spec.
+ private Runnable mEndCallback;
private final Object mLock;
private final int mDisplayId;
@@ -1197,6 +1248,7 @@ public class FullScreenMagnificationController {
mValueAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
mValueAnimator.setFloatValues(0.0f, 1.0f);
mValueAnimator.addUpdateListener(this);
+ mValueAnimator.addListener(this);
}
/**
@@ -1216,24 +1268,36 @@ public class FullScreenMagnificationController {
}
}
- public void updateSentSpecMainThread(MagnificationSpec spec, boolean animate) {
+ void updateSentSpecMainThread(MagnificationSpec spec, Runnable endCallback) {
if (mValueAnimator.isRunning()) {
+ // Avoid AnimationEnd Callback.
+ mEndCallback = null;
mValueAnimator.cancel();
}
+ mEndCallback = endCallback;
// If the current and sent specs don't match, update the sent spec.
synchronized (mLock) {
final boolean changed = !mSentMagnificationSpec.equals(spec);
if (changed) {
- if (animate) {
+ if (mEndCallback != null) {
animateMagnificationSpecLocked(spec);
} else {
setMagnificationSpecLocked(spec);
}
+ } else {
+ sendEndCallbackMainThread();
}
}
}
+ private void sendEndCallbackMainThread() {
+ if (mEndCallback != null) {
+ mEndCallback.run();
+ mEndCallback = null;
+ }
+ }
+
@GuardedBy("mLock")
private void setMagnificationSpecLocked(MagnificationSpec spec) {
if (mEnabled) {
@@ -1270,6 +1334,26 @@ public class FullScreenMagnificationController {
}
}
}
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ sendEndCallbackMainThread();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
}
private static class ScreenStateObserver extends BroadcastReceiver {
@@ -1395,4 +1479,9 @@ public class FullScreenMagnificationController {
return mAnimationDuration;
}
}
+
+ @Nullable
+ private static Runnable transformToStubRunnable(boolean animate) {
+ return animate ? STUB_RUNNABLE : null;
+ }
}
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 103151dcdda5..7ee607c3eab4 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -219,7 +219,7 @@ public class AppPredictionPerUserService extends
if (connected) {
synchronized (mLock) {
if (mZombie) {
- // Sanity check - shouldn't happen
+ // Validation check - shouldn't happen
if (mRemoteService == null) {
Slog.w(TAG, "Cannot resurrect sessions because remote service is null");
return;
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index b229e9f30180..3562205834b4 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -16,11 +16,13 @@
package com.android.server.appwidget;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import com.android.server.AppWidgetBackupBridge;
-import com.android.server.FgThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
/**
* SystemService that publishes an IAppWidgetService.
@@ -49,12 +51,12 @@ public class AppWidgetService extends SystemService {
}
@Override
- public void onStopUser(int userHandle) {
- mImpl.onUserStopped(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mImpl.onUserStopped(user.getUserIdentifier());
}
@Override
- public void onSwitchUser(int userHandle) {
- mImpl.reloadWidgetsMaskedStateForGroup(userHandle);
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mImpl.reloadWidgetsMaskedStateForGroup(to.getUserIdentifier());
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 089861bee479..663fd6259fd4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -84,6 +84,7 @@ import com.android.internal.util.Preconditions;
import com.android.internal.util.SyncResultReceiver;
import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.SystemService.TargetUser;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -363,7 +364,7 @@ public final class AutofillManagerService
}
@Override // from SystemService
- public void onSwitchUser(int userHandle) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
mUi.hideAll(null);
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 5a9320f61b38..b0755ac836e0 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -161,8 +161,9 @@ final class RemoteFillService extends ServiceConnector.Impl<IAutoFillService> {
@Override
public void onFailure(int requestId, CharSequence message) {
+ String errorMessage = message == null ? "" : String.valueOf(message);
fillRequest.completeExceptionally(
- new RuntimeException(String.valueOf(message)));
+ new RuntimeException(errorMessage));
}
});
return fillRequest;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 7ab4369b338a..1970b5774bbb 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1710,7 +1710,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if ((state & ViewState.STATE_AUTOFILLED_ONCE) != 0) {
final String datasetId = viewState.getDatasetId();
if (datasetId == null) {
- // Sanity check - should never happen.
+ // Validation check - should never happen.
Slog.w(TAG, "logContextCommitted(): no dataset id on " + viewState);
continue;
}
@@ -1844,7 +1844,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final ArrayMap<String, String> algorithms = userData.getFieldClassificationAlgorithms();
final ArrayMap<String, Bundle> args = userData.getFieldClassificationArgs();
- // Sanity check
+ // Validation check
if (userValues == null || categoryIds == null || userValues.length != categoryIds.length) {
final int valuesLength = userValues == null ? -1 : userValues.length;
final int idsLength = categoryIds == null ? -1 : categoryIds.length;
@@ -2668,12 +2668,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final String currentUrl = mUrlBar == null ? null
: mUrlBar.getText().toString().trim();
if (currentUrl == null) {
- // Sanity check - shouldn't happen.
+ // Validation check - shouldn't happen.
wtf(null, "URL bar value changed, but current value is null");
return;
}
if (value == null || ! value.isText()) {
- // Sanity check - shouldn't happen.
+ // Validation check - shouldn't happen.
wtf(null, "URL bar value changed to null or non-text: %s", value);
return;
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index c839ce94bd64..12e6e10d9047 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -19,6 +19,7 @@ package com.android.server.backup;
import static java.util.Collections.emptySet;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -60,6 +61,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.backup.utils.RandomAccessFileUtils;
import java.io.File;
@@ -1605,13 +1607,13 @@ public class BackupManagerService extends IBackupManager.Stub {
}
@Override
- public void onUnlockUser(int userId) {
- sInstance.onUnlockUser(userId);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ sInstance.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userId) {
- sInstance.onStopUser(userId);
+ public void onUserStopping(@NonNull TargetUser user) {
+ sInstance.onStopUser(user.getUserIdentifier());
}
@VisibleForTesting
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 2de26b7c4bd2..3ab81cbb313f 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -2307,7 +2307,7 @@ public class UserBackupManagerService {
public void enqueueFullBackup(String packageName, long lastBackedUp) {
FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp);
synchronized (mQueueLock) {
- // First, sanity check that we aren't adding a duplicate. Slow but
+ // First, check that we aren't adding a duplicate. Slow but
// straightforward; we'll have at most on the order of a few hundred
// items in this list.
dequeueFullBackupLocked(packageName);
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index a69bd6b62264..0a117746ea3f 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -24,8 +24,6 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_HEA
import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_VERSION;
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
-import android.app.backup.BackupManager;
-import android.app.backup.BackupManager.OperationType;
import android.app.backup.IFullBackupRestoreObserver;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -143,7 +141,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
private OutputStream emitAesBackupHeader(StringBuilder headerbuf,
OutputStream ofstream) throws Exception {
- // User key will be used to encrypt the master key.
+ // User key will be used to encrypt the encryption key.
byte[] newUserSalt = mUserBackupManagerService
.randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
SecretKey userKey = PasswordUtils
@@ -151,16 +149,16 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
newUserSalt,
PasswordUtils.PBKDF2_HASH_ROUNDS);
- // the master key is random for each backup
- byte[] masterPw = new byte[256 / 8];
- mUserBackupManagerService.getRng().nextBytes(masterPw);
+ // the encryption key is random for each backup
+ byte[] encryptionKey = new byte[256 / 8];
+ mUserBackupManagerService.getRng().nextBytes(encryptionKey);
byte[] checksumSalt = mUserBackupManagerService
.randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
- // primary encryption of the datastream with the random key
+ // primary encryption of the datastream with the encryption key
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
- SecretKeySpec masterKeySpec = new SecretKeySpec(masterPw, "AES");
- c.init(Cipher.ENCRYPT_MODE, masterKeySpec);
+ SecretKeySpec encryptionKeySpec = new SecretKeySpec(encryptionKey, "AES");
+ c.init(Cipher.ENCRYPT_MODE, encryptionKeySpec);
OutputStream finalOutput = new CipherOutputStream(ofstream, c);
// line 4: name of encryption algorithm
@@ -169,7 +167,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
// line 5: user password salt [hex]
headerbuf.append(PasswordUtils.byteArrayToHex(newUserSalt));
headerbuf.append('\n');
- // line 6: master key checksum salt [hex]
+ // line 6: encryption key checksum salt [hex]
headerbuf.append(PasswordUtils.byteArrayToHex(checksumSalt));
headerbuf.append('\n');
// line 7: number of PBKDF2 rounds used [decimal]
@@ -184,21 +182,21 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
headerbuf.append(PasswordUtils.byteArrayToHex(IV));
headerbuf.append('\n');
- // line 9: master IV + key blob, encrypted by the user key [hex]. Blob format:
+ // line 9: encryption IV + key blob, encrypted by the user key [hex]. Blob format:
// [byte] IV length = Niv
// [array of Niv bytes] IV itself
- // [byte] master key length = Nmk
- // [array of Nmk bytes] master key itself
- // [byte] MK checksum hash length = Nck
- // [array of Nck bytes] master key checksum hash
+ // [byte] encryption key length = Nek
+ // [array of Nek bytes] encryption key itself
+ // [byte] encryption key checksum hash length = Nck
+ // [array of Nck bytes] encryption key checksum hash
//
- // The checksum is the (master key + checksum salt), run through the
+ // The checksum is the (encryption key + checksum salt), run through the
// stated number of PBKDF2 rounds
IV = c.getIV();
- byte[] mk = masterKeySpec.getEncoded();
+ byte[] mk = encryptionKeySpec.getEncoded();
byte[] checksum = PasswordUtils
.makeKeyChecksum(PBKDF_CURRENT,
- masterKeySpec.getEncoded(),
+ encryptionKeySpec.getEncoded(),
checksumSalt, PasswordUtils.PBKDF2_HASH_ROUNDS);
ByteArrayOutputStream blob = new ByteArrayOutputStream(IV.length + mk.length
@@ -347,15 +345,15 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
// When line 4 is not "none", then additional header data follows:
//
// line 5: user password salt [hex]
- // line 6: master key checksum salt [hex]
- // line 7: number of PBKDF2 rounds to use (same for user & master) [decimal]
+ // line 6: encryption key checksum salt [hex]
+ // line 7: number of PBKDF2 rounds to use (same for user & encryption key) [decimal]
// line 8: IV of the user key [hex]
- // line 9: master key blob [hex]
- // IV of the master key, master key itself, master key checksum hash
+ // line 9: encryption key blob [hex]
+ // IV of the encryption key, encryption key itself, encryption key checksum hash
//
- // The master key checksum is the master key plus its checksum salt, run through
+ // The encryption key checksum is the encryption key plus its checksum salt, run through
// 10k rounds of PBKDF2. This is used to verify that the user has supplied the
- // correct password for decrypting the archive: the master key decrypted from
+ // correct password for decrypting the archive: the encryption key decrypted from
// the archive using the user-supplied password is also run through PBKDF2 in
// this way, and if the result does not match the checksum as stored in the
// archive, then we know that the user-supplied password does not match the
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 82bed3b57f16..e42d3bd0e352 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -379,7 +379,7 @@ public class FullRestoreEngine extends RestoreEngine {
}
}
- // Sanity check: make sure we never give data to the wrong app. This
+ // Make sure we never give data to the wrong app. This
// should never happen but a little paranoia here won't go amiss.
if (okay && !pkg.equals(mAgentPackage)) {
Slog.e(TAG, "Restoring data for " + pkg
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index 01b40fbff201..923bb086f914 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -212,10 +212,9 @@ public class PerformAdbRestoreTask implements Runnable {
return buffer.toString();
}
- private static InputStream attemptMasterKeyDecryption(String decryptPassword, String algorithm,
- byte[] userSalt, byte[] ckSalt,
- int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream,
- boolean doLog) {
+ private static InputStream attemptEncryptionKeyDecryption(String decryptPassword,
+ String algorithm, byte[] userSalt, byte[] ckSalt, int rounds, String userIvHex,
+ String encryptionKeyBlobHex, InputStream rawInStream, boolean doLog) {
InputStream result = null;
try {
@@ -228,31 +227,31 @@ public class PerformAdbRestoreTask implements Runnable {
c.init(Cipher.DECRYPT_MODE,
new SecretKeySpec(userKey.getEncoded(), "AES"),
ivSpec);
- byte[] mkCipher = PasswordUtils.hexToByteArray(masterKeyBlobHex);
+ byte[] mkCipher = PasswordUtils.hexToByteArray(encryptionKeyBlobHex);
byte[] mkBlob = c.doFinal(mkCipher);
- // first, the master key IV
+ // first, the encryption key IV
int offset = 0;
int len = mkBlob[offset++];
IV = Arrays.copyOfRange(mkBlob, offset, offset + len);
offset += len;
- // then the master key itself
+ // then the encryption key itself
len = mkBlob[offset++];
- byte[] mk = Arrays.copyOfRange(mkBlob,
+ byte[] encryptionKey = Arrays.copyOfRange(mkBlob,
offset, offset + len);
offset += len;
- // and finally the master key checksum hash
+ // and finally the encryption key checksum hash
len = mkBlob[offset++];
byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
offset, offset + len);
- // now validate the decrypted master key against the checksum
- byte[] calculatedCk = PasswordUtils.makeKeyChecksum(algorithm, mk, ckSalt,
+ // now validate the decrypted encryption key against the checksum
+ byte[] calculatedCk = PasswordUtils.makeKeyChecksum(algorithm, encryptionKey, ckSalt,
rounds);
if (Arrays.equals(calculatedCk, mkChecksum)) {
ivSpec = new IvParameterSpec(IV);
c.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(mk, "AES"),
+ new SecretKeySpec(encryptionKey, "AES"),
ivSpec);
// Only if all of the above worked properly will 'result' be assigned
result = new CipherInputStream(rawInStream, c);
@@ -265,7 +264,7 @@ public class PerformAdbRestoreTask implements Runnable {
}
} catch (BadPaddingException e) {
// This case frequently occurs when the wrong password is used to decrypt
- // the master key. Use the identical "incorrect password" log text as is
+ // the encryption key. Use the identical "incorrect password" log text as is
// used in the checksum failure log in order to avoid providing additional
// information to an attacker.
if (doLog) {
@@ -273,7 +272,7 @@ public class PerformAdbRestoreTask implements Runnable {
}
} catch (IllegalBlockSizeException e) {
if (doLog) {
- Slog.w(TAG, "Invalid block size in master key");
+ Slog.w(TAG, "Invalid block size in encryption key");
}
} catch (NoSuchAlgorithmException e) {
if (doLog) {
@@ -309,15 +308,15 @@ public class PerformAdbRestoreTask implements Runnable {
int rounds = Integer.parseInt(readHeaderLine(rawInStream)); // 7
String userIvHex = readHeaderLine(rawInStream); // 8
- String masterKeyBlobHex = readHeaderLine(rawInStream); // 9
+ String encryptionKeyBlobHex = readHeaderLine(rawInStream); // 9
- // decrypt the master key blob
- result = attemptMasterKeyDecryption(decryptPassword, PBKDF_CURRENT,
- userSalt, ckSalt, rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
+ // decrypt the encryption key blob
+ result = attemptEncryptionKeyDecryption(decryptPassword, PBKDF_CURRENT, userSalt,
+ ckSalt, rounds, userIvHex, encryptionKeyBlobHex, rawInStream, false);
if (result == null && pbkdf2Fallback) {
- result = attemptMasterKeyDecryption(
+ result = attemptEncryptionKeyDecryption(
decryptPassword, PBKDF_FALLBACK, userSalt, ckSalt,
- rounds, userIvHex, masterKeyBlobHex, rawInStream, true);
+ rounds, userIvHex, encryptionKeyBlobHex, rawInStream, true);
}
} else {
Slog.w(TAG, "Unsupported encryption method: " + encryptionName);
diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
index 162921528e95..ee05c2b9ea3b 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
@@ -37,7 +37,6 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.util.ArrayUtils;
-import com.android.server.LocalServices;
import com.android.server.backup.transport.TransportClient;
import com.google.android.collect.Sets;
@@ -49,8 +48,8 @@ import java.util.Set;
*/
public class BackupEligibilityRules {
private static final boolean DEBUG = false;
- // Whitelist of system packages that are eligible for backup in non-system users.
- private static final Set<String> systemPackagesWhitelistedForAllUsers =
+ // List of system packages that are eligible for backup in non-system users.
+ private static final Set<String> systemPackagesAllowedForAllUsers =
Sets.newArraySet(PACKAGE_MANAGER_SENTINEL, PLATFORM_PACKAGE_NAME);
private final PackageManager mPackageManager;
@@ -97,9 +96,10 @@ public class BackupEligibilityRules {
// 2. they run as a system-level uid
if (UserHandle.isCore(app.uid)) {
- // and the backup is happening for non-system user on a non-whitelisted package.
+ // and the backup is happening for a non-system user on a package that is not explicitly
+ // allowed.
if (mUserId != UserHandle.USER_SYSTEM
- && !systemPackagesWhitelistedForAllUsers.contains(app.packageName)) {
+ && !systemPackagesAllowedForAllUsers.contains(app.packageName)) {
return false;
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 6d8f9a35bfaa..eb38f5199ce5 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -28,6 +28,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainRunna
import static java.util.concurrent.TimeUnit.MINUTES;
import android.annotation.CheckResult;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.PendingIntent;
@@ -84,6 +85,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.wm.ActivityTaskManagerInternal;
import org.xmlpull.v1.XmlPullParser;
@@ -189,7 +191,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
@Override
- public void onUnlockUser(int userHandle) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ int userHandle = user.getUserIdentifier();
Set<Association> associations = readAllAssociations(userHandle);
if (associations == null || associations.isEmpty()) {
return;
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index b241bd16d3ee..ad1986a6669f 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -69,6 +69,7 @@ public abstract class PackageManagerInternal {
public static final int PACKAGE_WIFI = 13;
public static final int PACKAGE_COMPANION = 14;
public static final int PACKAGE_RETAIL_DEMO = 15;
+ public static final int PACKAGE_OVERLAY_CONFIG_SIGNATURE = 16;
@IntDef(flag = true, prefix = "RESOLVE_", value = {
RESOLVE_NON_BROWSER_ONLY,
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index f1d74bb08b85..a3c04be02c6f 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -59,16 +59,16 @@ public class BinderCallsStatsService extends Binder {
/** Resolves the work source of an incoming binder transaction. */
static class AuthorizedWorkSourceProvider implements BinderInternal.WorkSourceProvider {
- private ArraySet<Integer> mAppIdWhitelist;
+ private ArraySet<Integer> mAppIdTrustlist;
AuthorizedWorkSourceProvider() {
- mAppIdWhitelist = new ArraySet<>();
+ mAppIdTrustlist = new ArraySet<>();
}
public int resolveWorkSourceUid(int untrustedWorkSourceUid) {
final int callingUid = getCallingUid();
final int appId = UserHandle.getAppId(callingUid);
- if (mAppIdWhitelist.contains(appId)) {
+ if (mAppIdTrustlist.contains(appId)) {
final int workSource = untrustedWorkSourceUid;
final boolean isWorkSourceSet = workSource != Binder.UNSET_WORKSOURCE;
return isWorkSourceSet ? workSource : callingUid;
@@ -77,13 +77,13 @@ public class BinderCallsStatsService extends Binder {
}
public void systemReady(Context context) {
- mAppIdWhitelist = createAppidWhitelist(context);
+ mAppIdTrustlist = createAppidTrustlist(context);
}
public void dump(PrintWriter pw, AppIdToPackageMap packageMap) {
pw.println("AppIds of apps that can set the work source:");
- final ArraySet<Integer> whitelist = mAppIdWhitelist;
- for (Integer appId : whitelist) {
+ final ArraySet<Integer> trustlist = mAppIdTrustlist;
+ for (Integer appId : trustlist) {
pw.println("\t- " + packageMap.mapAppId(appId));
}
}
@@ -92,12 +92,12 @@ public class BinderCallsStatsService extends Binder {
return Binder.getCallingUid();
}
- private ArraySet<Integer> createAppidWhitelist(Context context) {
- // Use a local copy instead of mAppIdWhitelist to prevent concurrent read access.
- final ArraySet<Integer> whitelist = new ArraySet<>();
+ private ArraySet<Integer> createAppidTrustlist(Context context) {
+ // Use a local copy instead of mAppIdTrustlist to prevent concurrent read access.
+ final ArraySet<Integer> trustlist = new ArraySet<>();
// We trust our own process.
- whitelist.add(UserHandle.getAppId(Process.myUid()));
+ trustlist.add(UserHandle.getAppId(Process.myUid()));
// We only need to initialize it once. UPDATE_DEVICE_STATS is a system permission.
final PackageManager pm = context.getPackageManager();
final String[] permissions = { android.Manifest.permission.UPDATE_DEVICE_STATS };
@@ -110,12 +110,12 @@ public class BinderCallsStatsService extends Binder {
try {
final int uid = pm.getPackageUid(pkgInfo.packageName, queryFlags);
final int appId = UserHandle.getAppId(uid);
- whitelist.add(appId);
+ trustlist.add(appId);
} catch (NameNotFoundException e) {
Slog.e(TAG, "Cannot find uid for package name " + pkgInfo.packageName, e);
}
}
- return whitelist;
+ return trustlist;
}
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 2e4d44cef416..f372c6f85ec6 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -96,6 +96,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+ private static final String BLUETOOTH_PRIVILEGED =
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED;
private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
@@ -306,6 +308,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
};
public boolean onFactoryReset() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
+ "Need BLUETOOTH_PRIVILEGED permission");
+
// Wait for stable state if bluetooth is temporary state.
int state = getState();
if (state == BluetoothAdapter.STATE_BLE_TURNING_ON
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
index 0bcd9373c660..1a1eecd0f439 100644
--- a/services/core/java/com/android/server/BluetoothService.java
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -16,10 +16,14 @@
package com.android.server;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.os.UserManager;
+import com.android.server.SystemService.TargetUser;
+
class BluetoothService extends SystemService {
private BluetoothManagerService mBluetoothManagerService;
private boolean mInitialized = false;
@@ -52,16 +56,16 @@ class BluetoothService extends SystemService {
}
@Override
- public void onSwitchUser(int userHandle) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
if (!mInitialized) {
initialize();
} else {
- mBluetoothManagerService.handleOnSwitchUser(userHandle);
+ mBluetoothManagerService.handleOnSwitchUser(to.getUserIdentifier());
}
}
@Override
- public void onUnlockUser(int userHandle) {
- mBluetoothManagerService.handleOnUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mBluetoothManagerService.handleOnUnlockUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index c87dcd7874f8..b3d4085288dd 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -38,6 +38,7 @@ import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
+import android.telecom.TelecomManager;
import android.util.MutableBoolean;
import android.util.Slog;
import android.view.KeyEvent;
@@ -457,6 +458,8 @@ public class GestureLauncherService extends SystemService {
}
} else if (launchPanic) {
Slog.i(TAG, "Panic gesture detected, launching panic.");
+ launchPanic = handlePanicButtonGesture();
+ // TODO(b/160006048): Add logging
}
mMetricsLogger.histogram("power_consecutive_short_tap_count",
mPowerButtonSlowConsecutiveTaps);
@@ -501,6 +504,46 @@ public class GestureLauncherService extends SystemService {
}
}
+ /**
+ * @return true if panic ui was launched, false otherwise.
+ */
+ @VisibleForTesting
+ boolean handlePanicButtonGesture() {
+ // TODO(b/160006048): This is the wrong way to launch panic ui. Rewrite this to go
+ // through SysUI
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+ "GestureLauncher:handlePanicButtonGesture");
+ try {
+ boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+ if (!userSetupComplete) {
+ if (DBG) {
+ Slog.d(TAG, String.format(
+ "userSetupComplete = %s, ignoring panic gesture.",
+ userSetupComplete));
+ }
+ return false;
+ }
+ if (DBG) {
+ Slog.d(TAG, String.format(
+ "userSetupComplete = %s, performing panic gesture.",
+ userSetupComplete));
+ }
+ // TODO(b/160006048): Not all devices have telephony. Check system feature first.
+ TelecomManager telecomManager = (TelecomManager) mContext.getSystemService(
+ Context.TELECOM_SERVICE);
+ mContext.startActivity(telecomManager.createLaunchEmergencyDialerIntent(null).addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP).putExtra(
+ "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE",
+ 2)); // 2 maps to power button, forcing into fast emergency dialer experience.
+ return true;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ }
+ }
+
private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 3148a6205871..a3bcbbe25e88 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -20,6 +20,7 @@ import static android.app.ActivityManager.UID_OBSERVER_ACTIVE;
import static android.app.ActivityManager.UID_OBSERVER_GONE;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -60,6 +61,7 @@ import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.SystemService.TargetUser;
import com.android.server.wm.ActivityTaskManagerInternal;
import dalvik.system.DexFile;
@@ -236,16 +238,18 @@ public final class PinnerService extends SystemService {
* individual apps. Make sure that user's preference is pinned into memory.
*/
@Override
- public void onSwitchUser(int userHandle) {
- if (!mUserManager.isManagedProfile(userHandle)) {
- sendPinAppsMessage(userHandle);
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ int userId = to.getUserIdentifier();
+ if (!mUserManager.isManagedProfile(userId)) {
+ sendPinAppsMessage(userId);
}
}
@Override
- public void onUnlockUser(int userHandle) {
- if (!mUserManager.isManagedProfile(userHandle)) {
- sendPinAppsMessage(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ int userId = user.getUserIdentifier();
+ if (!mUserManager.isManagedProfile(userId)) {
+ sendPinAppsMessage(userId);
}
}
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index e5d0021a2bdf..0038dc2e8da0 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -80,10 +80,16 @@ public class ServiceWatcher implements ServiceConnection {
default void onError() {}
}
+ /** Function to run on binder interface when first bound. */
+ public interface OnBindRunner {
+ /** Called to run client code with the binder. */
+ void run(IBinder binder, ComponentName service) throws RemoteException;
+ }
+
/**
* Information on the service ServiceWatcher has selected as the best option for binding.
*/
- public static final class ServiceInfo implements Comparable<ServiceInfo> {
+ private static final class ServiceInfo implements Comparable<ServiceInfo> {
public static final ServiceInfo NONE = new ServiceInfo(Integer.MIN_VALUE, null,
UserHandle.USER_NULL, false);
@@ -179,25 +185,25 @@ public class ServiceWatcher implements ServiceConnection {
private final Handler mHandler;
private final Intent mIntent;
- @Nullable private final BinderRunner mOnBind;
+ @Nullable private final OnBindRunner mOnBind;
@Nullable private final Runnable mOnUnbind;
// read/write from handler thread only
private int mCurrentUserId;
// write from handler thread only, read anywhere
- private volatile ServiceInfo mServiceInfo;
+ private volatile ServiceInfo mTargetService;
private volatile IBinder mBinder;
public ServiceWatcher(Context context, String action,
- @Nullable BinderRunner onBind, @Nullable Runnable onUnbind,
+ @Nullable OnBindRunner onBind, @Nullable Runnable onUnbind,
@BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
this(context, FgThread.getHandler(), action, onBind, onUnbind, enableOverlayResId,
nonOverlayPackageResId);
}
public ServiceWatcher(Context context, Handler handler, String action,
- @Nullable BinderRunner onBind, @Nullable Runnable onUnbind,
+ @Nullable OnBindRunner onBind, @Nullable Runnable onUnbind,
@BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
mContext = context;
mHandler = handler;
@@ -214,7 +220,7 @@ public class ServiceWatcher implements ServiceConnection {
mCurrentUserId = UserHandle.USER_NULL;
- mServiceInfo = ServiceInfo.NONE;
+ mTargetService = ServiceInfo.NONE;
mBinder = null;
}
@@ -304,7 +310,7 @@ public class ServiceWatcher implements ServiceConnection {
}
}
- if (forceRebind || !bestServiceInfo.equals(mServiceInfo)) {
+ if (forceRebind || !bestServiceInfo.equals(mTargetService)) {
rebind(bestServiceInfo);
}
}
@@ -312,32 +318,32 @@ public class ServiceWatcher implements ServiceConnection {
private void rebind(ServiceInfo newServiceInfo) {
Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
- if (!mServiceInfo.equals(ServiceInfo.NONE)) {
+ if (!mTargetService.equals(ServiceInfo.NONE)) {
if (D) {
- Log.i(TAG, "[" + mIntent.getAction() + "] unbinding from " + mServiceInfo);
+ Log.i(TAG, "[" + mIntent.getAction() + "] unbinding from " + mTargetService);
}
mContext.unbindService(this);
- onServiceDisconnected(mServiceInfo.component);
- mServiceInfo = ServiceInfo.NONE;
+ onServiceDisconnected(mTargetService.component);
+ mTargetService = ServiceInfo.NONE;
}
- mServiceInfo = newServiceInfo;
- if (mServiceInfo.equals(ServiceInfo.NONE)) {
+ mTargetService = newServiceInfo;
+ if (mTargetService.equals(ServiceInfo.NONE)) {
return;
}
- Preconditions.checkState(mServiceInfo.component != null);
+ Preconditions.checkState(mTargetService.component != null);
if (D) {
- Log.i(TAG, getLogPrefix() + " binding to " + mServiceInfo);
+ Log.i(TAG, getLogPrefix() + " binding to " + mTargetService);
}
- Intent bindIntent = new Intent(mIntent).setComponent(mServiceInfo.component);
+ Intent bindIntent = new Intent(mIntent).setComponent(mTargetService.component);
if (!mContext.bindServiceAsUser(bindIntent, this,
BIND_AUTO_CREATE | BIND_NOT_FOREGROUND | BIND_NOT_VISIBLE,
- mHandler, UserHandle.of(mServiceInfo.userId))) {
- mServiceInfo = ServiceInfo.NONE;
+ mHandler, UserHandle.of(mTargetService.userId))) {
+ mTargetService = ServiceInfo.NONE;
Log.e(TAG, getLogPrefix() + " unexpected bind failure - retrying later");
mHandler.postDelayed(() -> onBestServiceChanged(false), RETRY_DELAY_MS);
}
@@ -355,11 +361,11 @@ public class ServiceWatcher implements ServiceConnection {
mBinder = binder;
if (mOnBind != null) {
try {
- mOnBind.run(binder);
+ mOnBind.run(binder, component);
} catch (RuntimeException | RemoteException e) {
// binders may propagate some specific non-RemoteExceptions from the other side
// through the binder as well - we cannot allow those to crash the system server
- Log.e(TAG, getLogPrefix() + " exception running on " + mServiceInfo, e);
+ Log.e(TAG, getLogPrefix() + " exception running on " + component, e);
}
}
}
@@ -406,7 +412,7 @@ public class ServiceWatcher implements ServiceConnection {
void onPackageChanged(String packageName) {
// force a rebind if the changed package was the currently connected package
- onBestServiceChanged(packageName.equals(mServiceInfo.getPackageName()));
+ onBestServiceChanged(packageName.equals(mTargetService.getPackageName()));
}
/**
@@ -425,7 +431,7 @@ public class ServiceWatcher implements ServiceConnection {
} catch (RuntimeException | RemoteException e) {
// binders may propagate some specific non-RemoteExceptions from the other side
// through the binder as well - we cannot allow those to crash the system server
- Log.e(TAG, getLogPrefix() + " exception running on " + mServiceInfo, e);
+ Log.e(TAG, getLogPrefix() + " exception running on " + mTargetService, e);
runner.onError();
}
});
@@ -437,14 +443,14 @@ public class ServiceWatcher implements ServiceConnection {
@Override
public String toString() {
- return mServiceInfo.toString();
+ return mTargetService.toString();
}
/**
* Dump for debugging.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("service=" + mServiceInfo);
+ pw.println("target service=" + mTargetService);
pw.println("connected=" + (mBinder != null));
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1520dd351c97..eca6036ebf8e 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -55,6 +55,7 @@ import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -152,6 +153,7 @@ import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.LockPatternUtils;
+import com.android.server.SystemService.TargetUser;
import com.android.server.pm.Installer;
import com.android.server.storage.AppFuseBridge;
import com.android.server.storage.StorageSessionController;
@@ -259,23 +261,23 @@ class StorageManagerService extends IStorageManager.Stub
}
@Override
- public void onSwitchUser(int userHandle) {
- mStorageManagerService.mCurrentUserId = userHandle;
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mStorageManagerService.mCurrentUserId = to.getUserIdentifier();
}
@Override
- public void onUnlockUser(int userHandle) {
- mStorageManagerService.onUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mStorageManagerService.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onCleanupUser(int userHandle) {
- mStorageManagerService.onCleanupUser(userHandle);
+ public void onUserStopped(@NonNull TargetUser user) {
+ mStorageManagerService.onCleanupUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- mStorageManagerService.onStopUser(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mStorageManagerService.onStopUser(user.getUserIdentifier());
}
@Override
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 45d53a14d1e9..1496e926b95b 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemApi.Client;
-import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.UserInfo;
@@ -263,26 +262,6 @@ public abstract class SystemService {
}
/**
- * @deprecated subclasses should extend {@link #onUserStarting(TargetUser)} instead
- * (which by default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onStartUser(@UserIdInt int userId) {}
-
- /**
- * @deprecated subclasses should extend {@link #onUserStarting(TargetUser)} instead
- * (which by default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onStartUser(@NonNull UserInfo userInfo) {
- onStartUser(userInfo.id);
- }
-
- /**
* Called when a new user is starting, for system services to initialize any per-user
* state they maintain for running users.
*
@@ -292,27 +271,6 @@ public abstract class SystemService {
* @param user target user
*/
public void onUserStarting(@NonNull TargetUser user) {
- onStartUser(user.getUserInfo());
- }
-
- /**
- * @deprecated subclasses should extend {@link #onUserUnlocking(TargetUser)} instead (which by
- * default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onUnlockUser(@UserIdInt int userId) {}
-
- /**
- * @deprecated subclasses should extend {@link #onUserUnlocking(TargetUser)} instead (which by
- * default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onUnlockUser(@NonNull UserInfo userInfo) {
- onUnlockUser(userInfo.id);
}
/**
@@ -333,7 +291,6 @@ public abstract class SystemService {
* @param user target user
*/
public void onUserUnlocking(@NonNull TargetUser user) {
- onUnlockUser(user.getUserInfo());
}
/**
@@ -348,26 +305,6 @@ public abstract class SystemService {
}
/**
- * @deprecated subclasses should extend {@link #onUserSwitching(TargetUser, TargetUser)} instead
- * (which by default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onSwitchUser(@UserIdInt int toUserId) {}
-
- /**
- * @deprecated subclasses should extend {@link #onUserSwitching(TargetUser, TargetUser)} instead
- * (which by default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onSwitchUser(@Nullable UserInfo from, @NonNull UserInfo to) {
- onSwitchUser(to.id);
- }
-
- /**
* Called when switching to a different foreground user, for system services that have
* special behavior for whichever user is currently in the foreground. This is called
* before any application processes are aware of the new user.
@@ -382,28 +319,6 @@ public abstract class SystemService {
* @param to the user switching to
*/
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
- onSwitchUser((from == null ? null : from.getUserInfo()), to.getUserInfo());
- }
-
- /**
- * @deprecated subclasses should extend {@link #onUserStopping(TargetUser)} instead
- * (which by default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onStopUser(@UserIdInt int userId) {}
-
- /**
- * @deprecated subclasses should extend {@link #onUserStopping(TargetUser)} instead
- * (which by default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onStopUser(@NonNull UserInfo user) {
- onStopUser(user.id);
-
}
/**
@@ -420,27 +335,6 @@ public abstract class SystemService {
* @param user target user
*/
public void onUserStopping(@NonNull TargetUser user) {
- onStopUser(user.getUserInfo());
- }
-
- /**
- * @deprecated subclasses should extend {@link #onUserStopped(TargetUser)} instead (which by
- * default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onCleanupUser(@UserIdInt int userId) {}
-
- /**
- * @deprecated subclasses should extend {@link #onUserStopped(TargetUser)} instead (which by
- * default calls this method).
- *
- * @hide
- */
- @Deprecated
- public void onCleanupUser(@NonNull UserInfo user) {
- onCleanupUser(user.id);
}
/**
@@ -454,7 +348,6 @@ public abstract class SystemService {
* @param user target user
*/
public void onUserStopped(@NonNull TargetUser user) {
- onCleanupUser(user.getUserInfo());
}
/**
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index a4c6c8751d93..6d71c8e68f77 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -34,7 +34,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.net.LinkProperties;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -46,8 +45,6 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.telephony.Annotation;
-import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SrvccState;
import android.telephony.BarringInfo;
@@ -80,7 +77,9 @@ import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
+import android.util.ArrayMap;
import android.util.LocalLog;
+import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
@@ -103,6 +102,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
/**
* Since phone process can be restarted, this class provides a centralized place
@@ -111,11 +111,11 @@ import java.util.NoSuchElementException;
* Change-Id: I450c968bda93767554b5188ee63e10c9f43c5aa4 fixes bugs 16148026
* and 15973975 by saving the phoneId of the registrant and then using the
* phoneId when deciding to to make a callback. This is necessary because
- * a subId changes from to a dummy value when a SIM is removed and thus won't
+ * a subId changes from to a placeholder value when a SIM is removed and thus won't
* compare properly. Because getPhoneIdFromSubId(int subId) handles
- * the dummy value conversion we properly do the callbacks.
+ * the placeholder value conversion we properly do the callbacks.
*
- * Eventually we may want to remove the notion of dummy value but for now this
+ * Eventually we may want to remove the notion of placeholder value but for now this
* looks like the best approach.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -302,13 +302,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
@RadioPowerState
private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
- private final LocalLog mLocalLog = new LocalLog(100);
+ private final LocalLog mLocalLog = new LocalLog(200);
- private final LocalLog mListenLog = new LocalLog(100);
+ private final LocalLog mListenLog = new LocalLog(00);
- // Per-phoneMap of APN Type to DataConnectionState
- private List<Map<Integer, PreciseDataConnectionState>> mPreciseDataConnectionStates =
- new ArrayList<Map<Integer, PreciseDataConnectionState>>();
+ /**
+ * Per-phone map of precise data connection state. The key of the map is the pair of transport
+ * type and APN setting. This is the cache to prevent redundant callbacks to the listeners.
+ * A precise data connection with state {@link TelephonyManager#DATA_DISCONNECTED} removes
+ * its entry from the map.
+ */
+ private List<Map<Pair<Integer, ApnSetting>, PreciseDataConnectionState>>
+ mPreciseDataConnectionStates;
static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK =
PhoneStateListener.LISTEN_REGISTRATION_FAILURE
@@ -521,7 +526,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
- mPreciseDataConnectionStates.add(new HashMap<Integer, PreciseDataConnectionState>());
+ mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mTelephonyDisplayInfos[i] = null;
}
@@ -610,7 +615,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
- mPreciseDataConnectionStates.add(new HashMap<Integer, PreciseDataConnectionState>());
+ mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mTelephonyDisplayInfos[i] = null;
}
@@ -1687,38 +1692,25 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
*
* @param phoneId the phoneId carrying the data connection
* @param subId the subscriptionId for the data connection
- * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags.
* @param preciseState a PreciseDataConnectionState that has info about the data connection
*/
@Override
- public void notifyDataConnectionForSubscriber(
- int phoneId, int subId, @ApnType int apnType, PreciseDataConnectionState preciseState) {
+ public void notifyDataConnectionForSubscriber(int phoneId, int subId,
+ @NonNull PreciseDataConnectionState preciseState) {
if (!checkNotifyPermission("notifyDataConnection()" )) {
return;
}
- String apn = "";
- int state = TelephonyManager.DATA_UNKNOWN;
- int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- LinkProperties linkProps = null;
+ ApnSetting apnSetting = preciseState.getApnSetting();
- if (preciseState != null) {
- apn = preciseState.getDataConnectionApn();
- state = preciseState.getState();
- networkType = preciseState.getNetworkType();
- linkProps = preciseState.getLinkProperties();
- }
- if (VDBG) {
- log("notifyDataConnectionForSubscriber: subId=" + subId
- + " state=" + state + "' apn='" + apn
- + "' apnType=" + apnType + " networkType=" + networkType
- + "' preciseState=" + preciseState);
- }
+ int apnTypes = apnSetting.getApnTypeBitmask();
+ int state = preciseState.getState();
+ int networkType = preciseState.getNetworkType();
synchronized (mRecords) {
if (validatePhoneId(phoneId)) {
// We only call the callback when the change is for default APN type.
- if ((ApnSetting.TYPE_DEFAULT & apnType) != 0
+ if ((ApnSetting.TYPE_DEFAULT & apnTypes) != 0
&& (mDataConnectionState[phoneId] != state
|| mDataConnectionNetworkType[phoneId] != networkType)) {
String str = "onDataConnectionStateChanged("
@@ -1747,19 +1739,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mDataConnectionNetworkType[phoneId] = networkType;
}
- boolean needsNotify = false;
- // State has been cleared for this APN Type
- if (preciseState == null) {
- // We try clear the state and check if the state was previously not cleared
- needsNotify = mPreciseDataConnectionStates.get(phoneId).remove(apnType) != null;
- } else {
- // We need to check to see if the state actually changed
- PreciseDataConnectionState oldPreciseState =
- mPreciseDataConnectionStates.get(phoneId).put(apnType, preciseState);
- needsNotify = !preciseState.equals(oldPreciseState);
- }
-
- if (needsNotify) {
+ Pair<Integer, ApnSetting> key = Pair.create(preciseState.getTransportType(),
+ preciseState.getApnSetting());
+ PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId)
+ .remove(key);
+ if (!Objects.equals(oldState, preciseState)) {
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
@@ -1771,52 +1755,22 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
}
- }
- }
- handleRemoveListLocked();
- }
+ handleRemoveListLocked();
- broadcastDataConnectionStateChanged(state, apn, apnType, subId);
- }
+ broadcastDataConnectionStateChanged(phoneId, subId, preciseState);
- /**
- * Stub to satisfy the ITelephonyRegistry aidl interface; do not use this function.
- * @see #notifyDataConnectionFailedForSubscriber
- */
- public void notifyDataConnectionFailed(String apnType) {
- loge("This function should not be invoked");
- }
+ String str = "notifyDataConnectionForSubscriber: phoneId=" + phoneId + " subId="
+ + subId + " " + preciseState;
+ log(str);
+ mLocalLog.log(str);
+ }
- private void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, int apnType) {
- if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
- return;
- }
- if (VDBG) {
- log("notifyDataConnectionFailedForSubscriber: subId=" + subId
- + " apnType=" + apnType);
- }
- synchronized (mRecords) {
- if (validatePhoneId(phoneId)) {
- mPreciseDataConnectionStates.get(phoneId).put(
- apnType,
- new PreciseDataConnectionState.Builder()
- .setApnTypes(apnType)
- .build());
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
- && idMatch(r.subId, subId, phoneId)) {
- try {
- r.callback.onPreciseDataConnectionStateChanged(
- mPreciseDataConnectionStates.get(phoneId).get(apnType));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
- }
+ // If the state is disconnected, it would be the end of life cycle of a data
+ // connection, so remove it from the cache.
+ if (preciseState.getState() != TelephonyManager.DATA_DISCONNECTED) {
+ mPreciseDataConnectionStates.get(phoneId).put(key, preciseState);
}
}
-
- handleRemoveListLocked();
}
}
@@ -1970,41 +1924,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
@Override
- public void notifyPreciseDataConnectionFailed(int phoneId, int subId, @ApnType int apnType,
- String apn, @DataFailureCause int failCause) {
- if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
- return;
- }
-
- // precise notify invokes imprecise notify
- notifyDataConnectionFailedForSubscriber(phoneId, subId, apnType);
-
- synchronized (mRecords) {
- if (validatePhoneId(phoneId)) {
- mPreciseDataConnectionStates.get(phoneId).put(
- apnType,
- new PreciseDataConnectionState.Builder()
- .setApnTypes(apnType)
- .setFailCause(failCause)
- .build());
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
- && idMatch(r.subId, subId, phoneId)) {
- try {
- r.callback.onPreciseDataConnectionStateChanged(
- mPreciseDataConnectionStates.get(phoneId).get(apnType));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
- }
- }
- }
- handleRemoveListLocked();
- }
- }
-
- @Override
public void notifySrvccStateChanged(int subId, @SrvccState int state) {
if (!checkNotifyPermission("notifySrvccStateChanged()")) {
return;
@@ -2574,16 +2493,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
- private void broadcastDataConnectionStateChanged(int state, String apn,
- int apnType, int subId) {
+ private void broadcastDataConnectionStateChanged(int slotIndex, int subId,
+ @NonNull PreciseDataConnectionState pdcs) {
// Note: not reporting to the battery stats service here, because the
// status bar takes care of that after taking into account all of the
// required info.
Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
- intent.putExtra(PHONE_CONSTANTS_STATE_KEY, TelephonyUtils.dataStateToString(state));
- intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn);
+ intent.putExtra(PHONE_CONSTANTS_STATE_KEY,
+ TelephonyUtils.dataStateToString(pdcs.getState()));
+ intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName());
intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY,
- ApnSetting.getApnTypesStringFromBitmask(apnType));
+ ApnSetting.getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask()));
+ intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex);
intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE);
}
@@ -2969,7 +2890,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
/**
* Returns a string representation of the radio technology (network type)
* currently in use on the device.
- * @param subId for which network type is returned
+ * @param type for which network type is returned
* @return the name of the radio technology
*
*/
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 915189c085c2..df9dee89f5a2 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -16,7 +16,15 @@
package com.android.server;
+import static android.app.UiModeManager.DEFAULT_PRIORITY;
+import static android.app.UiModeManager.MODE_NIGHT_AUTO;
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
+import static android.app.UiModeManager.MODE_NIGHT_YES;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.util.TimeUtils.isTimeBetween;
+
import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -64,6 +72,7 @@ import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.DumpUtils;
+import com.android.server.SystemService.TargetUser;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
@@ -81,13 +90,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import static android.app.UiModeManager.DEFAULT_PRIORITY;
-import static android.app.UiModeManager.MODE_NIGHT_AUTO;
-import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
-import static android.app.UiModeManager.MODE_NIGHT_YES;
-import static android.os.UserHandle.USER_SYSTEM;
-import static android.util.TimeUtils.isTimeBetween;
-
final class UiModeManagerService extends SystemService {
private static final String TAG = UiModeManager.class.getSimpleName();
private static final boolean LOG = false;
@@ -322,8 +324,7 @@ final class UiModeManagerService extends SystemService {
}
@Override
- public void onSwitchUser(int userHandle) {
- super.onSwitchUser(userHandle);
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver);
verifySetupWizardCompleted();
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 7dc0b3a8ecd6..35e88eb804cb 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -106,6 +106,7 @@ import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
@@ -161,14 +162,14 @@ public class AccountManagerService
}
@Override
- public void onUnlockUser(int userHandle) {
- mService.onUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- Slog.i(TAG, "onStopUser " + userHandle);
- mService.purgeUserData(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ Slog.i(TAG, "onStopUser " + user);
+ mService.purgeUserData(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2f7d105e7a48..c187772df6e4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -341,6 +341,7 @@ import com.android.server.PackageWatchdog;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.SystemServiceManager;
import com.android.server.ThreadPriorityBooster;
import com.android.server.UserspaceRebootLogger;
@@ -2333,8 +2334,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public void onCleanupUser(int userId) {
- mService.mBatteryStatsService.onCleanupUser(userId);
+ public void onUserStopped(@NonNull TargetUser user) {
+ mService.mBatteryStatsService.onCleanupUser(user.getUserIdentifier());
}
public ActivityManagerService getService() {
@@ -2443,7 +2444,7 @@ public class ActivityManagerService extends IActivityManager.Stub
? Collections.emptyList()
: Arrays.asList(exemptions.split(","));
}
- if (!ZYGOTE_PROCESS.setApiBlacklistExemptions(mExemptions)) {
+ if (!ZYGOTE_PROCESS.setApiDenylistExemptions(mExemptions)) {
Slog.e(TAG, "Failed to set API blacklist exemptions!");
// leave mExemptionsStr as is, so we don't try to send the same list again.
mExemptions = Collections.emptyList();
@@ -14286,7 +14287,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
- int callingUid, int[] users, int[] broadcastWhitelist) {
+ int callingUid, int[] users, int[] broadcastAllowList) {
// TODO: come back and remove this assumption to triage all broadcasts
int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
@@ -14362,12 +14363,12 @@ public class ActivityManagerService extends IActivityManager.Stub
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
- if (receivers != null && broadcastWhitelist != null) {
+ if (receivers != null && broadcastAllowList != null) {
for (int i = receivers.size() - 1; i >= 0; i--) {
final int receiverAppId = UserHandle.getAppId(
receivers.get(i).activityInfo.applicationInfo.uid);
if (receiverAppId >= Process.FIRST_APPLICATION_UID
- && Arrays.binarySearch(broadcastWhitelist, receiverAppId) < 0) {
+ && Arrays.binarySearch(broadcastAllowList, receiverAppId) < 0) {
receivers.remove(i);
}
}
@@ -14477,7 +14478,7 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
int realCallingPid, int userId, boolean allowBackgroundActivityStarts,
@Nullable IBinder backgroundActivityStartsToken,
- @Nullable int[] broadcastWhitelist) {
+ @Nullable int[] broadcastAllowList) {
intent = new Intent(intent);
final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
@@ -14486,10 +14487,10 @@ public class ActivityManagerService extends IActivityManager.Stub
intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
}
- if (userId == UserHandle.USER_ALL && broadcastWhitelist != null) {
- Slog.e(TAG, "broadcastWhitelist only applies when sending to individual users. "
+ if (userId == UserHandle.USER_ALL && broadcastAllowList != null) {
+ Slog.e(TAG, "broadcastAllowList only applies when sending to individual users. "
+ "Assuming restrictive whitelist.");
- broadcastWhitelist = new int[]{};
+ broadcastAllowList = new int[]{};
}
// By default broadcasts do not go to stopped apps.
@@ -14981,7 +14982,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
receivers = collectReceiverComponents(
- intent, resolvedType, callingUid, users, broadcastWhitelist);
+ intent, resolvedType, callingUid, users, broadcastAllowList);
}
if (intent.getComponent() == null) {
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
@@ -15011,13 +15012,13 @@ public class ActivityManagerService extends IActivityManager.Stub
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
+ " replacePending=" + replacePending);
- if (registeredReceivers != null && broadcastWhitelist != null) {
+ if (registeredReceivers != null && broadcastAllowList != null) {
// if a uid whitelist was provided, remove anything in the application space that wasn't
// in it.
for (int i = registeredReceivers.size() - 1; i >= 0; i--) {
final int owningAppId = UserHandle.getAppId(registeredReceivers.get(i).owningUid);
if (owningAppId >= Process.FIRST_APPLICATION_UID
- && Arrays.binarySearch(broadcastWhitelist, owningAppId) < 0) {
+ && Arrays.binarySearch(broadcastAllowList, owningAppId) < 0) {
registeredReceivers.remove(i);
}
}
@@ -17996,7 +17997,7 @@ public class ActivityManagerService extends IActivityManager.Stub
public int broadcastIntent(Intent intent,
IIntentReceiver resultTo,
String[] requiredPermissions,
- boolean serialized, int userId, int[] appIdWhitelist) {
+ boolean serialized, int userId, int[] appIdAllowList) {
synchronized (ActivityManagerService.this) {
intent = verifyBroadcastLocked(intent);
@@ -18011,7 +18012,7 @@ public class ActivityManagerService extends IActivityManager.Stub
null /*options*/, serialized, false /*sticky*/, callingPid, callingUid,
callingUid, callingPid, userId, false /*allowBackgroundStarts*/,
null /*tokenNeededForBackgroundActivityStarts*/,
- appIdWhitelist);
+ appIdAllowList);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 43e3a04ad032..d9fde0f6728a 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -16,8 +16,6 @@
package com.android.server.am;
-import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
-
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_COMPACTION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FREEZER;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -256,7 +254,7 @@ public final class CachedAppOptimizer {
ProcessDependencies processDependencies) {
mAm = am;
mCachedAppOptimizerThread = new ServiceThread("CachedAppOptimizerThread",
- THREAD_PRIORITY_FOREGROUND, true);
+ Process.THREAD_GROUP_SYSTEM, true);
mProcStateThrottle = new HashSet<>();
mProcessDependencies = processDependencies;
mTestCallback = callback;
@@ -280,8 +278,6 @@ public final class CachedAppOptimizer {
updateProcStateThrottle();
updateUseFreezer();
}
- Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
- Process.THREAD_GROUP_SYSTEM);
}
/**
@@ -411,12 +407,15 @@ public final class CachedAppOptimizer {
mUseCompaction = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_USE_COMPACTION, DEFAULT_USE_COMPACTION);
- if (mUseCompaction) {
+ if (mUseCompaction && mCompactionHandler == null) {
if (!mCachedAppOptimizerThread.isAlive()) {
mCachedAppOptimizerThread.start();
}
mCompactionHandler = new MemCompactionHandler();
+
+ Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
+ Process.THREAD_GROUP_SYSTEM);
}
}
@@ -470,13 +469,16 @@ public final class CachedAppOptimizer {
mUseFreezer = isFreezerSupported();
}
- if (mUseFreezer) {
+ if (mUseFreezer && mFreezeHandler == null) {
Slog.d(TAG_AM, "Freezer enabled");
if (!mCachedAppOptimizerThread.isAlive()) {
mCachedAppOptimizerThread.start();
}
mFreezeHandler = new FreezeHandler();
+
+ Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
+ Process.THREAD_GROUP_SYSTEM);
}
}
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 00b33c4c3e68..8970ec4c7bb7 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -92,7 +92,7 @@ final class CoreSettingsObserver extends ContentObserver {
sGlobalSettingToTypeMap.put(
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, String.class);
sGlobalSettingToTypeMap.put(
- Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST, String.class);
+ Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST, String.class);
sGlobalSettingToTypeMap.put(
Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, int.class);
diff --git a/services/core/java/com/android/server/appbinding/AppBindingService.java b/services/core/java/com/android/server/appbinding/AppBindingService.java
index 7e63e728701e..5db6dc7ccc15 100644
--- a/services/core/java/com/android/server/appbinding/AppBindingService.java
+++ b/services/core/java/com/android/server/appbinding/AppBindingService.java
@@ -45,6 +45,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.am.PersistentConnection;
import com.android.server.appbinding.finders.AppServiceFinder;
import com.android.server.appbinding.finders.CarrierMessagingClientServiceFinder;
@@ -125,18 +126,18 @@ public class AppBindingService extends Binder {
}
@Override
- public void onStartUser(int userHandle) {
- mService.onStartUser(userHandle);
+ public void onUserStarting(@NonNull TargetUser user) {
+ mService.onStartUser(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(int userId) {
- mService.onUnlockUser(userId);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- mService.onStopUser(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mService.onStopUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 7051e4a294e2..e128d993ab63 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -108,7 +108,8 @@ public class AttentionManagerService extends SystemService {
private final PowerManager mPowerManager;
private final Object mLock;
@GuardedBy("mLock")
- private IAttentionService mService;
+ @VisibleForTesting
+ protected IAttentionService mService;
@GuardedBy("mLock")
private AttentionCheckCacheBuffer mAttentionCheckCacheBuffer;
@GuardedBy("mLock")
@@ -158,7 +159,8 @@ public class AttentionManagerService extends SystemService {
}
/** Resolves and sets up the attention service if it had not been done yet. */
- private boolean isServiceAvailable() {
+ @VisibleForTesting
+ protected boolean isServiceAvailable() {
if (mComponentName == null) {
mComponentName = resolveAttentionService(mContext);
}
@@ -168,12 +170,12 @@ public class AttentionManagerService extends SystemService {
/**
* Returns {@code true} if attention service is supported on this device.
*/
- private boolean isAttentionServiceSupported() {
+ @VisibleForTesting
+ protected boolean isAttentionServiceSupported() {
return isServiceEnabled() && isServiceConfigured(mContext);
}
- @VisibleForTesting
- protected boolean isServiceEnabled() {
+ private boolean isServiceEnabled() {
return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE, KEY_SERVICE_ENABLED,
DEFAULT_SERVICE_ENABLED);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2d77d6f8add8..366f30318cd5 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -414,13 +414,6 @@ public class AudioService extends IAudioService.Stub
AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT
};
- private static Set<Integer> sDeviceVolumeBehaviorSupportedDeviceOutSet = new HashSet<>(
- Arrays.asList(
- AudioSystem.DEVICE_OUT_HDMI,
- AudioSystem.DEVICE_OUT_HDMI_ARC,
- AudioSystem.DEVICE_OUT_SPDIF,
- AudioSystem.DEVICE_OUT_LINE));
-
private final boolean mUseFixedVolume;
// If absolute volume is supported in AVRCP device
@@ -4952,11 +4945,6 @@ public class AudioService extends IAudioService.Stub
private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut,
@AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
- if (!sDeviceVolumeBehaviorSupportedDeviceOutSet.contains(audioSystemDeviceOut)) {
- // unsupported for now
- throw new IllegalArgumentException("Unsupported device type " + audioSystemDeviceOut);
- }
-
// update device masks based on volume behavior
switch (deviceVolumeBehavior) {
case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
@@ -4990,20 +4978,14 @@ public class AudioService extends IAudioService.Stub
* @param device the audio output device type
* @return the volume behavior for the device
*/
- public @AudioManager.DeviceVolumeBehaviorState int getDeviceVolumeBehavior(
- @NonNull AudioDeviceAttributes device) {
+ public @AudioManager.DeviceVolumeBehavior
+ int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
// verify permissions
enforceModifyAudioRoutingPermission();
// translate Java device type to native device type (for the devices masks for full / fixed)
final int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
device.getType());
- if (!sDeviceVolumeBehaviorSupportedDeviceOutSet.contains(audioSystemDeviceOut)
- && audioSystemDeviceOut != AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
- && audioSystemDeviceOut != AudioSystem.DEVICE_OUT_HEARING_AID) {
- throw new IllegalArgumentException("Unsupported volume behavior "
- + audioSystemDeviceOut);
- }
int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut);
if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
@@ -5855,11 +5837,13 @@ public class AudioService extends IAudioService.Stub
caller);
}
// fire changed intents for all streams
- mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
- mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
- mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
- mStreamVolumeAlias[mStreamType]);
- sendBroadcastToAll(mVolumeChanged);
+ if (index != oldIndex) {
+ mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
+ mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
+ mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
+ mStreamVolumeAlias[mStreamType]);
+ sendBroadcastToAll(mVolumeChanged);
+ }
}
return changed;
}
@@ -7497,6 +7481,7 @@ public class AudioService extends IAudioService.Stub
pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume);
pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume);
pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
+ pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
pw.print(" mExtVolumeController="); pw.println(mExtVolumeController);
pw.print(" mHdmiCecSink="); pw.println(mHdmiCecSink);
pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
@@ -9078,7 +9063,7 @@ public class AudioService extends IAudioService.Stub
}
private void restoreDeviceVolumeBehavior() {
- for (int deviceType : sDeviceVolumeBehaviorSupportedDeviceOutSet) {
+ for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
if (DEBUG_VOL) {
Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
}
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index b4c41b274dbe..5e8f1ef0db85 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -632,21 +632,28 @@ public class BtHelper {
return result;
}
+ // Return `(null)` if given BluetoothDevice is null. Otherwise, return the anonymized address.
+ private String getAnonymizedAddress(BluetoothDevice btDevice) {
+ return btDevice == null ? "(null)" : btDevice.getAnonymizedAddress();
+ }
+
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
//@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
private void setBtScoActiveDevice(BluetoothDevice btDevice) {
- Log.i(TAG, "setBtScoActiveDevice: " + mBluetoothHeadsetDevice + " -> " + btDevice);
+ Log.i(TAG, "setBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice)
+ + " -> " + getAnonymizedAddress(btDevice));
final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice;
if (Objects.equals(btDevice, previousActiveDevice)) {
return;
}
if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) {
Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device "
- + previousActiveDevice);
+ + getAnonymizedAddress(previousActiveDevice));
}
if (!handleBtScoActiveDeviceChange(btDevice, true)) {
- Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice);
+ Log.e(TAG, "setBtScoActiveDevice() failed to add new device "
+ + getAnonymizedAddress(btDevice));
// set mBluetoothHeadsetDevice to null when failing to add new device
btDevice = null;
}
@@ -826,7 +833,8 @@ public class BtHelper {
mBluetoothHeadsetDevice, mScoAudioMode)) {
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
} else {
- Log.w(TAG, "requestScoState: connect to " + mBluetoothHeadsetDevice
+ Log.w(TAG, "requestScoState: connect to "
+ + getAnonymizedAddress(mBluetoothHeadsetDevice)
+ " failed, mScoAudioMode=" + mScoAudioMode);
broadcastScoConnectionState(
AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 0aeb7abe706e..4f37dccea42e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -194,19 +194,19 @@ public class BiometricScheduler {
return;
}
+ if (clientMonitor != mCurrentOperation.clientMonitor) {
+ Slog.e(getTag(), "[Ignoring Finish] " + clientMonitor + " does not match"
+ + " current: " + mCurrentOperation.clientMonitor);
+ return;
+ }
+
+ Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success);
mCurrentOperation.state = Operation.STATE_FINISHED;
if (mCurrentOperation.clientFinishCallback != null) {
mCurrentOperation.clientFinishCallback.onClientFinished(clientMonitor, success);
}
- if (clientMonitor != mCurrentOperation.clientMonitor) {
- throw new IllegalStateException("Mismatched operation, "
- + " current: " + mCurrentOperation.clientMonitor
- + " received: " + clientMonitor);
- }
-
- Slog.d(getTag(), "[Finished] " + clientMonitor + ", success: " + success);
if (mGestureAvailabilityDispatcher != null) {
mGestureAvailabilityDispatcher.markSensorActive(
mCurrentOperation.clientMonitor.getSensorId(), false /* active */);
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 61c99b88d113..88867fcfc46f 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -15,6 +15,8 @@
*/
package com.android.server.camera;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -43,6 +45,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.wm.WindowManagerInternal;
import java.util.ArrayList;
@@ -252,20 +255,20 @@ public class CameraServiceProxy extends SystemService
}
@Override
- public void onStartUser(int userHandle) {
+ public void onUserStarting(@NonNull TargetUser user) {
synchronized(mLock) {
if (mEnabledCameraUsers == null) {
// Initialize cameraserver, or update cameraserver if we are recovering
// from a crash.
- switchUserLocked(userHandle);
+ switchUserLocked(user.getUserIdentifier());
}
}
}
@Override
- public void onSwitchUser(int userHandle) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
synchronized(mLock) {
- switchUserLocked(userHandle);
+ switchUserLocked(to.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index ed3a223b5dd7..a0bc7d8954fb 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -19,6 +19,7 @@ package com.android.server.clipboard;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
@@ -59,6 +60,7 @@ import android.view.autofill.AutofillManagerInternal;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wm.WindowManagerInternal;
@@ -218,9 +220,9 @@ public class ClipboardService extends SystemService {
}
@Override
- public void onCleanupUser(int userId) {
+ public void onUserStopped(@NonNull TargetUser user) {
synchronized (mClipboards) {
- mClipboards.remove(userId);
+ mClipboards.remove(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index f8774b1b0054..7202f0f401f9 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -171,8 +171,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
mAllApps.add(UserHandle.getAppId(uid));
final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
- final boolean hasRestrictedPermission =
- hasRestrictedNetworkPermission(app.applicationInfo);
+ final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(uid)
+ || isCarryoverPackage(app.applicationInfo);
if (isNetwork || hasRestrictedPermission) {
Boolean permission = mApps.get(uid);
@@ -200,7 +200,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
for (int i = 0; i < systemPermission.size(); i++) {
ArraySet<String> perms = systemPermission.valueAt(i);
int uid = systemPermission.keyAt(i);
- int netdPermission = 0;
+ int netdPermission = PERMISSION_NONE;
// Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission.
if (perms != null) {
netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
@@ -225,20 +225,21 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
}
@VisibleForTesting
- boolean hasRestrictedNetworkPermission(@Nullable final ApplicationInfo appInfo) {
- if (appInfo == null) return false;
- // TODO : remove this check in the future(b/162295056). All apps should just
- // request the appropriate permission for their use case since android Q.
- if ((appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
+ // TODO : remove this check in the future(b/162295056). All apps should just request the
+ // appropriate permission for their use case since android Q.
+ boolean isCarryoverPackage(@Nullable final ApplicationInfo appInfo) {
+ if (appInfo == null) return false;
+ return (appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
// Backward compatibility for b/114245686, on devices that launched before Q daemons
// and apps running as the system UID are exempted from this check.
- || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q)) {
- return true;
- }
+ || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q);
+ }
- return hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, appInfo.uid)
- || hasPermission(NETWORK_STACK, appInfo.uid)
- || hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, appInfo.uid);
+ @VisibleForTesting
+ boolean hasRestrictedNetworkPermission(final int uid) {
+ return hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, uid)
+ || hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, uid)
+ || hasPermission(NETWORK_STACK, uid);
}
/** Returns whether the given uid has using background network permission. */
@@ -328,8 +329,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
try {
final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
- final boolean hasRestrictedPermission =
- hasRestrictedNetworkPermission(app.applicationInfo);
+ final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(uid)
+ || isCarryoverPackage(app.applicationInfo);
if (isNetwork || hasRestrictedPermission) {
currentPermission = hasRestrictedPermission;
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 9a910bf5e859..1294e9030f62 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,6 +20,7 @@ import static android.content.PermissionChecker.PERMISSION_GRANTED;
import android.Manifest;
import android.accounts.Account;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
@@ -75,6 +76,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.FileDescriptor;
@@ -124,26 +126,25 @@ public final class ContentService extends IContentService.Stub {
mService.onBootPhase(phase);
}
-
@Override
- public void onStartUser(int userHandle) {
- mService.onStartUser(userHandle);
+ public void onUserStarting(@NonNull TargetUser user) {
+ mService.onStartUser(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(int userHandle) {
- mService.onUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- mService.onStopUser(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mService.onStopUser(user.getUserIdentifier());
}
@Override
- public void onCleanupUser(int userHandle) {
+ public void onUserStopped(@NonNull TargetUser user) {
synchronized (mService.mCache) {
- mService.mCache.remove(userHandle);
+ mService.mCache.remove(user.getUserIdentifier());
}
}
}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index ec2b0c0a6830..ad3cd67ad65b 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -491,7 +491,14 @@ final class ColorFade {
mIsWideColor = SurfaceControl.getActiveColorMode(token)
== Display.COLOR_MODE_DISPLAY_P3;
- SurfaceControl.screenshot(token, s);
+ SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
+ mDisplayManagerInternal.systemScreenshot(mDisplayId);
+ s.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(),
+ screenshotBuffer.getColorSpace());
+
+ if (screenshotBuffer.containsSecureLayers()) {
+ mTransaction.setSecure(mSurfaceControl, true).apply();
+ }
st.updateTexImage();
st.getTransformMatrix(mTexMatrix);
} finally {
@@ -586,7 +593,6 @@ final class ColorFade {
}
if (mSurfaceControl == null) {
- Transaction t = new Transaction();
try {
final SurfaceControl.Builder builder = new SurfaceControl.Builder(mSurfaceSession)
.setName("ColorFade")
@@ -602,15 +608,16 @@ final class ColorFade {
return false;
}
- t.setLayerStack(mSurfaceControl, mDisplayLayerStack);
- t.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight);
+ mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack);
+ mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight);
+ mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal,
+ mDisplayId, mSurfaceControl);
+ mSurfaceLayout.onDisplayTransaction(mTransaction);
+ mTransaction.apply();
+
mSurface = new Surface();
mSurface.copyFrom(mSurfaceControl);
- mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal,
- mDisplayId, mSurfaceControl);
- mSurfaceLayout.onDisplayTransaction(t);
- t.apply();
}
return true;
}
@@ -652,7 +659,7 @@ final class ColorFade {
if (mSurfaceControl != null) {
mSurfaceLayout.dispose();
mSurfaceLayout = null;
- new Transaction().remove(mSurfaceControl).apply();
+ mTransaction.remove(mSurfaceControl).apply();
mSurface.release();
mSurfaceControl = null;
mSurfaceVisible = false;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index a00c22a409e9..0979ad67a8cd 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -104,6 +104,7 @@ import com.android.server.AnimationThread;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.UiThread;
import com.android.server.wm.SurfaceAnimationThread;
import com.android.server.wm.WindowManagerInternal;
@@ -417,7 +418,8 @@ public final class DisplayManagerService extends SystemService {
}
@Override
- public void onSwitchUser(@UserIdInt int newUserId) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ final int newUserId = to.getUserIdentifier();
final int userSerial = getUserManager().getUserSerialNumber(newUserId);
synchronized (mSyncRoot) {
if (mCurrentUserId != newUserId) {
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 95a98f1e9494..92a3ccfc9dd9 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -58,6 +58,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings.Secure;
@@ -76,6 +77,7 @@ import com.android.internal.util.DumpUtils;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
@@ -205,30 +207,24 @@ public final class ColorDisplayService extends SystemService {
}
@Override
- public void onStartUser(int userHandle) {
- super.onStartUser(userHandle);
-
+ public void onUserStarting(@NonNull TargetUser user) {
if (mCurrentUser == UserHandle.USER_NULL) {
final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
- message.arg1 = userHandle;
+ message.arg1 = user.getUserIdentifier();
mHandler.sendMessage(message);
}
}
@Override
- public void onSwitchUser(int userHandle) {
- super.onSwitchUser(userHandle);
-
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
- message.arg1 = userHandle;
+ message.arg1 = to.getUserIdentifier();
mHandler.sendMessage(message);
}
@Override
- public void onStopUser(int userHandle) {
- super.onStopUser(userHandle);
-
- if (mCurrentUser == userHandle) {
+ public void onUserStopping(@NonNull TargetUser user) {
+ if (mCurrentUser == user.getUserIdentifier()) {
final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
message.arg1 = UserHandle.USER_NULL;
mHandler.sendMessage(message);
@@ -819,7 +815,13 @@ public final class ColorDisplayService extends SystemService {
return LocalDateTime.MIN;
}
- private boolean setAppSaturationLevelInternal(String callingPackageName,
+ void setSaturationLevelInternal(int saturationLevel) {
+ final Message message = mHandler.obtainMessage(MSG_APPLY_GLOBAL_SATURATION);
+ message.arg1 = saturationLevel;
+ mHandler.sendMessage(message);
+ }
+
+ boolean setAppSaturationLevelInternal(String callingPackageName,
String affectedPackageName, int saturationLevel) {
return mAppSaturationController
.setSaturationLevel(callingPackageName, affectedPackageName, mCurrentUser,
@@ -1509,9 +1511,7 @@ public final class ColorDisplayService extends SystemService {
}
final long token = Binder.clearCallingIdentity();
try {
- final Message message = mHandler.obtainMessage(MSG_APPLY_GLOBAL_SATURATION);
- message.arg1 = level;
- mHandler.sendMessage(message);
+ setSaturationLevelInternal(level);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1724,5 +1724,22 @@ public final class ColorDisplayService extends SystemService {
Binder.restoreCallingIdentity(token);
}
}
+
+ @Override
+ public int handleShellCommand(ParcelFileDescriptor in,
+ ParcelFileDescriptor out, ParcelFileDescriptor err, String[] args) {
+ getContext().enforceCallingOrSelfPermission(
+ Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
+ "Permission required to use ADB color transform commands");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return new ColorDisplayShellCommand(ColorDisplayService.this)
+ .exec(this, in.getFileDescriptor(), out.getFileDescriptor(),
+ err.getFileDescriptor(),
+ args);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayShellCommand.java b/services/core/java/com/android/server/display/color/ColorDisplayShellCommand.java
new file mode 100644
index 000000000000..b4555f851d4d
--- /dev/null
+++ b/services/core/java/com/android/server/display/color/ColorDisplayShellCommand.java
@@ -0,0 +1,119 @@
+/*
+ * 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.display.color;
+
+import android.content.pm.PackageManagerInternal;
+import android.os.ShellCommand;
+
+import com.android.server.LocalServices;
+
+class ColorDisplayShellCommand extends ShellCommand {
+
+ private static final String USAGE = "usage: cmd color_display SUBCOMMAND [ARGS]\n"
+ + " help\n"
+ + " Shows this message.\n"
+ + " set-saturation LEVEL\n"
+ + " Sets the device saturation to the given LEVEL, 0-100 inclusive.\n"
+ + " set-layer-saturation CALLER_PACKAGE TARGET_PACKAGE LEVEL\n"
+ + " Sets the saturation LEVEL for all layers of the TARGET_PACKAGE, attributed\n"
+ + " to the CALLER_PACKAGE. The lowest LEVEL from any CALLER_PACKAGE is applied.\n";
+
+ private static final int ERROR = -1;
+ private static final int SUCCESS = 0;
+
+ private final ColorDisplayService mService;
+
+ ColorDisplayShellCommand(ColorDisplayService service) {
+ mService = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ switch (cmd) {
+ case "set-saturation":
+ return setSaturation();
+ case "set-layer-saturation":
+ return setLayerSaturation();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ }
+
+ private int setSaturation() {
+ final int level = getLevel();
+ if (level == ERROR) {
+ return ERROR;
+ }
+ mService.setSaturationLevelInternal(level);
+ return SUCCESS;
+ }
+
+ private int setLayerSaturation() {
+ final int level = getLevel();
+ if (level == ERROR) {
+ return ERROR;
+ }
+ final String callerPackageName = getPackageName();
+ if (callerPackageName == null) {
+ getErrPrintWriter().println("Error: CALLER_PACKAGE must be an installed package name");
+ return ERROR;
+ }
+ final String targetPackageName = getPackageName();
+ if (targetPackageName == null) {
+ getErrPrintWriter().println("Error: TARGET_PACKAGE must be an installed package name");
+ return ERROR;
+ }
+ mService.setAppSaturationLevelInternal(callerPackageName, targetPackageName, level);
+ return SUCCESS;
+ }
+
+ private String getPackageName() {
+ final String packageNameArg = getNextArg();
+ return LocalServices.getService(PackageManagerInternal.class).getPackage(packageNameArg)
+ == null
+ ? null : packageNameArg;
+ }
+
+ private int getLevel() {
+ final String levelArg = getNextArg();
+ if (levelArg == null) {
+ getErrPrintWriter().println("Error: Required argument LEVEL is unspecified");
+ return ERROR;
+ }
+ final int level;
+ try {
+ level = Integer.parseInt(levelArg);
+ } catch (NumberFormatException e) {
+ getErrPrintWriter().println("Error: LEVEL argument is not an integer");
+ return ERROR;
+ }
+ if (level < 0 || level > 100) {
+ getErrPrintWriter()
+ .println("Error: LEVEL argument must be an integer between 0 and 100");
+ return ERROR;
+ }
+ return level;
+ }
+
+ @Override
+ public void onHelp() {
+ getOutPrintWriter().print(USAGE);
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/ActiveSourceAction.java b/services/core/java/com/android/server/hdmi/ActiveSourceAction.java
index 3c4dae0f6467..c90f297e1485 100644
--- a/services/core/java/com/android/server/hdmi/ActiveSourceAction.java
+++ b/services/core/java/com/android/server/hdmi/ActiveSourceAction.java
@@ -39,15 +39,19 @@ public class ActiveSourceAction extends HdmiCecFeatureAction {
@Override
boolean start() {
mState = STATE_STARTED;
- sendCommand(HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(),
- source().mService.getPhysicalAddress()));
+ int logicalAddress = getSourceAddress();
+ int physicalAddress = getSourcePath();
+
+ sendCommand(HdmiCecMessageBuilder.buildActiveSource(logicalAddress, physicalAddress));
if (source().getType() == HdmiDeviceInfo.DEVICE_PLAYBACK) {
// Reports menu-status active to receive <User Control Pressed>.
sendCommand(
- HdmiCecMessageBuilder.buildReportMenuStatus(getSourceAddress(), mDestination,
+ HdmiCecMessageBuilder.buildReportMenuStatus(logicalAddress, mDestination,
Constants.MENU_STATE_ACTIVATED));
}
+
+ source().setActiveSource(logicalAddress, physicalAddress);
mState = STATE_FINISHED;
finish();
return true;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 7007f8b1df50..0576e91b79eb 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -3249,7 +3249,6 @@ public class HdmiControlService extends SystemService {
playback.setIsActiveSource(true);
playback.wakeUpIfActiveSource();
playback.maySendActiveSource(source);
- setActiveSource(playback.mAddress, physicalAddress);
}
if (deviceType == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
@@ -3260,7 +3259,6 @@ public class HdmiControlService extends SystemService {
audioSystem.setIsActiveSource(true);
audioSystem.wakeUpIfActiveSource();
audioSystem.maySendActiveSource(source);
- setActiveSource(audioSystem.mAddress, physicalAddress);
}
}
}
@@ -3283,13 +3281,11 @@ public class HdmiControlService extends SystemService {
if (audioSystem != null) {
audioSystem.setIsActiveSource(false);
}
- setActiveSource(playback.mAddress, physicalAddress);
} else {
if (audioSystem != null) {
audioSystem.setIsActiveSource(true);
audioSystem.wakeUpIfActiveSource();
audioSystem.maySendActiveSource(sourceAddress);
- setActiveSource(audioSystem.mAddress, physicalAddress);
}
}
}
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 2672f848f192..7bbcdaa2d473 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -43,6 +43,7 @@ import com.android.internal.infra.AbstractRemoteService;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -299,16 +300,16 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
}
@Override // from SystemService
- public void onUnlockUser(int userId) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
synchronized (mLock) {
- updateCachedServiceLocked(userId);
+ updateCachedServiceLocked(user.getUserIdentifier());
}
}
@Override // from SystemService
- public void onCleanupUser(int userId) {
+ public void onUserStopped(@NonNull TargetUser user) {
synchronized (mLock) {
- removeCachedServiceLocked(userId);
+ removeCachedServiceLocked(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 254285dfbd41..3cd70fecbf3d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -159,6 +159,7 @@ import com.android.internal.view.InputBindResult;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.inputmethod.InputMethodManagerInternal.InputMethodListListener;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings;
@@ -1596,10 +1597,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public void onSwitchUser(@UserIdInt int userHandle) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
// Called on ActivityManager thread.
synchronized (mService.mMethodMap) {
- mService.scheduleSwitchUserTaskLocked(userHandle, null /* clientToBeReset */);
+ mService.scheduleSwitchUserTaskLocked(to.getUserIdentifier(),
+ /* clientToBeReset= */ null);
}
}
@@ -1615,10 +1617,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public void onUnlockUser(final @UserIdInt int userHandle) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
// Called on ActivityManager thread.
mService.mHandler.sendMessage(mService.mHandler.obtainMessage(MSG_SYSTEM_UNLOCK_USER,
- userHandle /* arg1 */, 0 /* arg2 */));
+ /* arg1= */ user.getUserIdentifier(), /* arg2= */ 0));
}
}
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 2516e289f099..937514ca9139 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -94,6 +94,7 @@ import com.android.internal.view.InlineSuggestionsRequestInfo;
import com.android.internal.view.InputBindResult;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.wm.WindowManagerInternal;
import java.io.FileDescriptor;
@@ -249,23 +250,26 @@ public final class MultiClientInputMethodManagerService {
@MainThread
@Override
- public void onStartUser(@UserIdInt int userId) {
+ public void onUserStarting(@NonNull TargetUser user) {
mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
- OnWorkerThreadCallback::onStartUser, mOnWorkerThreadCallback, userId));
+ OnWorkerThreadCallback::onStartUser, mOnWorkerThreadCallback,
+ user.getUserIdentifier()));
}
@MainThread
@Override
- public void onUnlockUser(@UserIdInt int userId) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
- OnWorkerThreadCallback::onUnlockUser, mOnWorkerThreadCallback, userId));
+ OnWorkerThreadCallback::onUnlockUser, mOnWorkerThreadCallback,
+ user.getUserIdentifier()));
}
@MainThread
@Override
- public void onStopUser(@UserIdInt int userId) {
+ public void onUserStopping(@NonNull TargetUser user) {
mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
- OnWorkerThreadCallback::onStopUser, mOnWorkerThreadCallback, userId));
+ OnWorkerThreadCallback::onStopUser, mOnWorkerThreadCallback,
+ user.getUserIdentifier()));
}
}
diff --git a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
index e29471bdfd6b..eed1aac79166 100644
--- a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
+++ b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
@@ -17,6 +17,7 @@
package com.android.server.location;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Context;
import android.hardware.location.ActivityRecognitionHardware;
import android.hardware.location.IActivityRecognitionHardwareClient;
@@ -77,7 +78,7 @@ public class HardwareActivityRecognitionProxy {
return mServiceWatcher.register();
}
- private void onBind(IBinder binder) throws RemoteException {
+ private void onBind(IBinder binder, ComponentName service) throws RemoteException {
String descriptor = binder.getInterfaceDescriptor();
if (IActivityRecognitionHardwareWatcher.class.getCanonicalName().equals(descriptor)) {
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 2bcee2faa813..d778d242f571 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -19,6 +19,7 @@ package com.android.server.location;
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Context;
import android.location.Location;
import android.location.util.identity.CallerIdentity;
@@ -32,10 +33,12 @@ import com.android.internal.location.ILocationProvider;
import com.android.internal.location.ILocationProviderManager;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
+import com.android.internal.util.ArrayUtils;
import com.android.server.ServiceWatcher;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Objects;
/**
* Proxy for ILocationProvider implementations.
@@ -65,6 +68,8 @@ public class LocationProviderProxy extends AbstractLocationProvider {
@GuardedBy("mLock")
Proxy mProxy;
+ @GuardedBy("mLock")
+ @Nullable ComponentName mService;
private volatile ProviderRequest mRequest;
@@ -86,11 +91,12 @@ public class LocationProviderProxy extends AbstractLocationProvider {
return mServiceWatcher.register();
}
- private void onBind(IBinder binder) throws RemoteException {
+ private void onBind(IBinder binder, ComponentName service) throws RemoteException {
ILocationProvider provider = ILocationProvider.Stub.asInterface(binder);
synchronized (mLock) {
mProxy = new Proxy();
+ mService = service;
provider.setLocationProviderManager(mProxy);
ProviderRequest request = mRequest;
@@ -103,6 +109,7 @@ public class LocationProviderProxy extends AbstractLocationProvider {
private void onUnbind() {
synchronized (mLock) {
mProxy = null;
+ mService = null;
setState(State.EMPTY_STATE);
}
}
@@ -111,16 +118,16 @@ public class LocationProviderProxy extends AbstractLocationProvider {
public void onSetRequest(ProviderRequest request) {
mRequest = request;
mServiceWatcher.runOnBinder(binder -> {
- ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
- service.setRequest(request, request.workSource);
+ ILocationProvider provider = ILocationProvider.Stub.asInterface(binder);
+ provider.setRequest(request, request.workSource);
});
}
@Override
public void onExtraCommand(int uid, int pid, String command, Bundle extras) {
mServiceWatcher.runOnBinder(binder -> {
- ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
- service.sendExtraCommand(command, extras);
+ ILocationProvider provider = ILocationProvider.Stub.asInterface(binder);
+ provider.sendExtraCommand(command, extras);
});
}
@@ -129,12 +136,14 @@ public class LocationProviderProxy extends AbstractLocationProvider {
mServiceWatcher.dump(fd, pw, args);
}
- private static String guessPackageName(Context context, int uid) {
+ private static String guessPackageName(Context context, int uid, String packageName) {
String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
if (packageNames == null || packageNames.length == 0) {
// illegal state exception will propagate back through binders
throw new IllegalStateException(
"location provider from uid " + uid + " has no package information");
+ } else if (ArrayUtils.contains(packageNames, packageName)) {
+ return packageName;
} else {
return packageNames[0];
}
@@ -154,7 +163,8 @@ public class LocationProviderProxy extends AbstractLocationProvider {
CallerIdentity identity;
if (packageName == null) {
- packageName = guessPackageName(mContext, Binder.getCallingUid());
+ packageName = guessPackageName(mContext, Binder.getCallingUid(),
+ Objects.requireNonNull(mService).getPackageName());
// unsafe is ok since the package is coming direct from the package manager here
identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag);
} else {
@@ -175,7 +185,8 @@ public class LocationProviderProxy extends AbstractLocationProvider {
// if no identity is set yet, set it now
if (getIdentity() == null) {
- String packageName = guessPackageName(mContext, Binder.getCallingUid());
+ String packageName = guessPackageName(mContext, Binder.getCallingUid(),
+ Objects.requireNonNull(mService).getPackageName());
// unsafe is ok since the package is coming direct from the package manager here
setIdentity(CallerIdentity.fromBinderUnsafe(packageName, null));
}
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
index 2218079c7889..686a66bb4d97 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
@@ -63,7 +63,7 @@ public final class GeofenceProxy {
private GeofenceProxy(Context context, IGpsGeofenceHardware gpsGeofence) {
mGpsGeofenceHardware = Objects.requireNonNull(gpsGeofence);
mServiceWatcher = new ServiceWatcher(context, SERVICE_ACTION,
- this::updateGeofenceHardware, null,
+ (binder, service) -> updateGeofenceHardware(binder), null,
com.android.internal.R.bool.config_enableGeofenceOverlay,
com.android.internal.R.string.config_geofenceProviderPackageName);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index e56884832f0f..f1b89c7a433c 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -123,6 +123,7 @@ import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
import com.android.server.locksettings.LockSettingsStorage.PersistentData;
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
@@ -275,18 +276,18 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@Override
- public void onStartUser(int userHandle) {
- mLockSettingsService.onStartUser(userHandle);
+ public void onUserStarting(@NonNull TargetUser user) {
+ mLockSettingsService.onStartUser(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(int userHandle) {
- mLockSettingsService.onUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mLockSettingsService.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onCleanupUser(int userHandle) {
- mLockSettingsService.onCleanupUser(userHandle);
+ public void onUserStopped(@NonNull TargetUser user) {
+ mLockSettingsService.onCleanupUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index 9dae1b44117b..b9997e0c2ec8 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -221,8 +221,8 @@ final class MediaButtonReceiverHolder {
context.startActivityAsUser(mediaButtonIntent, userHandle);
break;
case COMPONENT_TYPE_SERVICE:
- context.startForegroundServiceAsUser(mediaButtonIntent,
- userHandle);
+ context.createContextAsUser(userHandle, 0).startForegroundService(
+ mediaButtonIntent);
break;
default:
// Legacy behavior for other cases.
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 9f6c18d5ec72..e2f70e320cb8 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -25,6 +25,8 @@ import static com.android.server.media.MediaKeyDispatcher.isLongPressOverridden;
import static com.android.server.media.MediaKeyDispatcher.isSingleTapOverridden;
import static com.android.server.media.MediaKeyDispatcher.isTripleTapOverridden;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.NotificationManager;
@@ -85,6 +87,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.Watchdog;
import com.android.server.Watchdog.Monitor;
@@ -333,19 +336,21 @@ public class MediaSessionService extends SystemService implements Monitor {
}
@Override
- public void onStartUser(int userId) {
- if (DEBUG) Log.d(TAG, "onStartUser: " + userId);
+ public void onUserStarting(@NonNull TargetUser user) {
+ if (DEBUG) Log.d(TAG, "onStartUser: " + user);
updateUser();
}
@Override
- public void onSwitchUser(int userId) {
- if (DEBUG) Log.d(TAG, "onSwitchUser: " + userId);
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ if (DEBUG) Log.d(TAG, "onSwitchUser: " + to);
updateUser();
}
@Override
- public void onCleanupUser(int userId) {
+ public void onUserStopped(@NonNull TargetUser targetUser) {
+ int userId = targetUser.getUserIdentifier();
+
if (DEBUG) Log.d(TAG, "onCleanupUser: " + userId);
synchronized (mLock) {
FullUserRecord user = getFullUserRecordLocked(userId);
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 1a749b34d85e..94776f8c7cb4 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -17,6 +17,8 @@
package com.android.server.media.projection;
import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.IProcessObserver;
@@ -48,6 +50,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.Watchdog;
import java.io.FileDescriptor;
@@ -122,8 +125,8 @@ public final class MediaProjectionManagerService extends SystemService
}
@Override
- public void onSwitchUser(int userId) {
- mMediaRouter.rebindAsUser(userId);
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mMediaRouter.rebindAsUser(to.getUserIdentifier());
synchronized (mLock) {
if (mProjectionGrant != null) {
mProjectionGrant.stop();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cf08e735bbd2..d71c33e6e6f5 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -261,6 +261,7 @@ import com.android.server.EventLogTags;
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.UiThread;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
@@ -322,7 +323,7 @@ public class NotificationManagerService extends SystemService {
static final boolean DEBUG_INTERRUPTIVENESS = SystemProperties.getBoolean(
"debug.notification.interruptiveness", false);
- static final int MAX_PACKAGE_NOTIFICATIONS = 25;
+ static final int MAX_PACKAGE_NOTIFICATIONS = 50;
static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
// message codes
@@ -2351,11 +2352,11 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void onUnlockUser(@NonNull UserInfo userInfo) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
mHandler.post(() -> {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryUnlockUser");
try {
- mHistoryManager.onUserUnlocked(userInfo.id);
+ mHistoryManager.onUserUnlocked(user.getUserIdentifier());
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
@@ -2363,11 +2364,11 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void onStopUser(@NonNull UserInfo userInfo) {
+ public void onUserStopping(@NonNull TargetUser user) {
mHandler.post(() -> {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryStopUser");
try {
- mHistoryManager.onUserStopped(userInfo.id);
+ mHistoryManager.onUserStopped(user.getUserIdentifier());
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
@@ -4861,7 +4862,6 @@ public class NotificationManagerService extends SystemService {
// calculate the final importance here
r.calculateImportance();
foundEnqueued = true;
- break;
}
}
if (!foundEnqueued) {
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index d6b1b27360ca..cb6e960b721d 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -27,6 +27,7 @@ import android.content.pm.PackageInfo;
import android.os.Build.VERSION_CODES;
import android.os.OverlayablePolicy;
import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Slog;
import java.io.IOException;
@@ -53,11 +54,20 @@ final class IdmapManager {
}
private final IdmapDaemon mIdmapDaemon;
- private final OverlayableInfoCallback mOverlayableCallback;
+ private final PackageManagerHelper mPackageManager;
- IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
- mOverlayableCallback = verifyCallback;
+ /**
+ * Package name of the reference package defined in 'config-signature' tag of
+ * SystemConfig or empty String if tag not defined. This package is vetted on scan by
+ * PackageManagerService that it's a system package and is used to check if overlay matches
+ * its signature in order to fulfill the config_signature policy.
+ */
+ private final String mConfigSignaturePackage;
+
+ IdmapManager(final IdmapDaemon idmapDaemon, final PackageManagerHelper packageManager) {
+ mPackageManager = packageManager;
mIdmapDaemon = idmapDaemon;
+ mConfigSignaturePackage = packageManager.getConfigSignaturePackage();
}
/**
@@ -139,7 +149,7 @@ final class IdmapManager {
int fulfilledPolicies = OverlayablePolicy.PUBLIC;
// Overlay matches target signature
- if (mOverlayableCallback.signaturesMatching(targetPackage.packageName,
+ if (mPackageManager.signaturesMatching(targetPackage.packageName,
overlayPackage.packageName, userId)) {
fulfilledPolicies |= OverlayablePolicy.SIGNATURE;
}
@@ -149,6 +159,16 @@ final class IdmapManager {
fulfilledPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
}
+ // If SystemConfig defines 'config-signature' package, given that
+ // this package is vetted by OverlayManagerService that it's a
+ // preinstalled package, check if overlay matches its signature.
+ if (!TextUtils.isEmpty(mConfigSignaturePackage)
+ && mPackageManager.signaturesMatching(mConfigSignaturePackage,
+ overlayPackage.packageName,
+ userId)) {
+ fulfilledPolicies |= OverlayablePolicy.CONFIG_SIGNATURE;
+ }
+
// Vendor partition (/vendor)
if (ai.isVendor()) {
return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION;
@@ -183,12 +203,12 @@ final class IdmapManager {
String targetOverlayableName = overlayPackage.targetOverlayableName;
if (targetOverlayableName != null) {
try {
- OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
+ OverlayableInfo overlayableInfo = mPackageManager.getOverlayableForTarget(
targetPackage.packageName, targetOverlayableName, userId);
if (overlayableInfo != null && overlayableInfo.actor != null) {
String actorPackageName = OverlayActorEnforcer.getPackageNameForActor(
- overlayableInfo.actor, mOverlayableCallback.getNamedActors()).first;
- if (mOverlayableCallback.signaturesMatching(actorPackageName,
+ overlayableInfo.actor, mPackageManager.getNamedActors()).first;
+ if (mPackageManager.signaturesMatching(actorPackageName,
overlayPackage.packageName, userId)) {
return true;
}
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index 2bc34998785b..8c03c6ce3092 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -45,7 +45,7 @@ public class OverlayActorEnforcer {
// By default, the reason is not logged to prevent leaks of why it failed
private static final boolean DEBUG_REASON = false;
- private final OverlayableInfoCallback mOverlayableCallback;
+ private final PackageManagerHelper mPackageManager;
/**
* @return nullable actor result with {@link ActorState} failure status
@@ -79,8 +79,8 @@ public class OverlayActorEnforcer {
return Pair.create(packageName, ActorState.ALLOWED);
}
- public OverlayActorEnforcer(@NonNull OverlayableInfoCallback overlayableCallback) {
- mOverlayableCallback = overlayableCallback;
+ public OverlayActorEnforcer(@NonNull PackageManagerHelper packageManager) {
+ mPackageManager = packageManager;
}
void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName,
@@ -110,7 +110,7 @@ public class OverlayActorEnforcer {
return ActorState.ALLOWED;
}
- String[] callingPackageNames = mOverlayableCallback.getPackagesForUid(callingUid);
+ String[] callingPackageNames = mPackageManager.getPackagesForUid(callingUid);
if (ArrayUtils.isEmpty(callingPackageNames)) {
return ActorState.NO_PACKAGES_FOR_UID;
}
@@ -125,12 +125,12 @@ public class OverlayActorEnforcer {
if (TextUtils.isEmpty(targetOverlayableName)) {
try {
- if (mOverlayableCallback.doesTargetDefineOverlayable(targetPackageName, userId)) {
+ if (mPackageManager.doesTargetDefineOverlayable(targetPackageName, userId)) {
return ActorState.MISSING_TARGET_OVERLAYABLE_NAME;
} else {
// If there's no overlayable defined, fallback to the legacy permission check
try {
- mOverlayableCallback.enforcePermission(
+ mPackageManager.enforcePermission(
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
// If the previous method didn't throw, check passed
@@ -146,7 +146,7 @@ public class OverlayActorEnforcer {
OverlayableInfo targetOverlayable;
try {
- targetOverlayable = mOverlayableCallback.getOverlayableForTarget(targetPackageName,
+ targetOverlayable = mPackageManager.getOverlayableForTarget(targetPackageName,
targetOverlayableName, userId);
} catch (IOException e) {
return ActorState.UNABLE_TO_GET_TARGET;
@@ -160,7 +160,7 @@ public class OverlayActorEnforcer {
if (TextUtils.isEmpty(actor)) {
// If there's no actor defined, fallback to the legacy permission check
try {
- mOverlayableCallback.enforcePermission(
+ mPackageManager.enforcePermission(
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
// If the previous method didn't throw, check passed
@@ -170,7 +170,7 @@ public class OverlayActorEnforcer {
}
}
- Map<String, Map<String, String>> namedActors = mOverlayableCallback.getNamedActors();
+ Map<String, Map<String, String>> namedActors = mPackageManager.getNamedActors();
Pair<String, ActorState> actorUriPair = getPackageNameForActor(actor, namedActors);
ActorState actorUriState = actorUriPair.second;
if (actorUriState != ActorState.ALLOWED) {
@@ -178,7 +178,7 @@ public class OverlayActorEnforcer {
}
String packageName = actorUriPair.first;
- PackageInfo packageInfo = mOverlayableCallback.getPackageInfo(packageName, userId);
+ PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, userId);
if (packageInfo == null) {
return ActorState.MISSING_APP_INFO;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 396815399874..a4debc16493a 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -31,6 +31,7 @@ import static android.os.Trace.traceEnd;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.BroadcastReceiver;
@@ -68,6 +69,7 @@ import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.pm.UserManagerService;
import libcore.util.EmptyArray;
@@ -303,7 +305,11 @@ public final class OverlayManagerService extends SystemService {
}
@Override
- public void onSwitchUser(final int newUserId) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ onSwitchUser(to.getUserIdentifier());
+ }
+
+ private void onSwitchUser(@UserIdInt int newUserId) {
try {
traceBegin(TRACE_TAG_RRO, "OMS#onSwitchUser " + newUserId);
// ensure overlays in the settings are up-to-date, and propagate
@@ -1053,8 +1059,7 @@ public final class OverlayManagerService extends SystemService {
}
}
- private static final class PackageManagerHelperImpl implements PackageManagerHelper,
- OverlayableInfoCallback {
+ private static final class PackageManagerHelperImpl implements PackageManagerHelper {
private final Context mContext;
private final IPackageManager mPackageManager;
@@ -1127,6 +1132,14 @@ public final class OverlayManagerService extends SystemService {
return overlays;
}
+ @Override
+ public String getConfigSignaturePackage() {
+ final String[] pkgs = mPackageManagerInternal.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE,
+ UserHandle.USER_SYSTEM);
+ return (pkgs.length == 0) ? null : pkgs[0];
+ }
+
@Nullable
@Override
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
diff --git a/services/core/java/com/android/server/om/OverlayReferenceMapper.java b/services/core/java/com/android/server/om/OverlayReferenceMapper.java
index cadb8e4746f3..a9dbb2f29535 100644
--- a/services/core/java/com/android/server/om/OverlayReferenceMapper.java
+++ b/services/core/java/com/android/server/om/OverlayReferenceMapper.java
@@ -18,14 +18,15 @@ package com.android.server.om;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import com.android.server.pm.parsing.pkg.AndroidPackage;
import android.text.TextUtils;
import android.util.Pair;
+import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.CollectionUtils;
import com.android.server.SystemConfig;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.util.Collections;
import java.util.HashMap;
@@ -72,6 +73,8 @@ import java.util.Set;
*/
public class OverlayReferenceMapper {
+ private static final String TAG = "OverlayReferenceMapper";
+
private final Object mLock = new Object();
/**
@@ -144,7 +147,7 @@ public class OverlayReferenceMapper {
public boolean isValidActor(@NonNull String targetName, @NonNull String actorPackageName) {
synchronized (mLock) {
- assertMapBuilt();
+ ensureMapBuilt();
Set<String> validSet = mActorPkgToPkgs.get(actorPackageName);
return validSet != null && validSet.contains(targetName);
}
@@ -292,10 +295,11 @@ public class OverlayReferenceMapper {
}
}
- private void assertMapBuilt() {
+ private void ensureMapBuilt() {
if (mDeferRebuild) {
- throw new IllegalStateException("The actor map must be built by calling "
- + "rebuildIfDeferred before it is queried");
+ rebuildIfDeferred();
+ Slog.w(TAG, "The actor map was queried before the system was ready, which may"
+ + "result in decreased performance.");
}
}
@@ -360,7 +364,7 @@ public class OverlayReferenceMapper {
* Given the actor string from an overlayable definition, return the actor's package name.
*/
@Nullable
- String getActorPkg(String actor);
+ String getActorPkg(@NonNull String actor);
/**
* Mock response of multiple overlay tags.
diff --git a/services/core/java/com/android/server/om/OverlayableInfoCallback.java b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
deleted file mode 100644
index 5066ecdd6316..000000000000
--- a/services/core/java/com/android/server/om/OverlayableInfoCallback.java
+++ /dev/null
@@ -1,83 +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.
- */
-
-package com.android.server.om;
-
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.om.OverlayableInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-
-import com.android.server.pm.PackageManagerServiceUtils;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Delegate to the system for querying information about overlayables and packages.
- */
-public interface OverlayableInfoCallback {
-
- /**
- * Read from the APK and AndroidManifest of a package to return the overlayable defined for
- * a given name.
- *
- * @throws IOException if the target can't be read
- */
- @Nullable
- OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
- @NonNull String targetOverlayableName, int userId)
- throws IOException;
-
- /**
- * @see PackageManager#getPackagesForUid(int)
- */
- @Nullable
- String[] getPackagesForUid(int uid);
-
- /**
- * @param userId user to filter package visibility by
- * @see PackageManager#getPackageInfo(String, int)
- */
- @Nullable
- PackageInfo getPackageInfo(@NonNull String packageName, int userId);
-
- /**
- * @return map of system pre-defined, uniquely named actors; keys are namespace,
- * value maps actor name to package name
- */
- @NonNull
- Map<String, Map<String, String>> getNamedActors();
-
- /**
- * @return true if the target package has declared an overlayable
- */
- boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
-
- /**
- * @throws SecurityException containing message if the caller doesn't have the given
- * permission
- */
- void enforcePermission(String permission, String message) throws SecurityException;
-
- /**
- * @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
- * in the system returns {@link PackageManager#SIGNATURE_MATCH}
- */
- boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
-}
diff --git a/services/core/java/com/android/server/om/PackageManagerHelper.java b/services/core/java/com/android/server/om/PackageManagerHelper.java
index ec9c5e64e390..b1a8b4ee4d9f 100644
--- a/services/core/java/com/android/server/om/PackageManagerHelper.java
+++ b/services/core/java/com/android/server/om/PackageManagerHelper.java
@@ -17,11 +17,17 @@
package com.android.server.om;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.OverlayableInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import com.android.server.pm.PackageManagerServiceUtils;
+
+import java.io.IOException;
import java.util.List;
+import java.util.Map;
/**
* Delegate for {@link PackageManager} and {@link PackageManagerInternal} functionality,
@@ -30,7 +36,65 @@ import java.util.List;
* @hide
*/
interface PackageManagerHelper {
+ /**
+ * @return true if the target package has declared an overlayable
+ */
+ boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
+
+ /**
+ * @throws SecurityException containing message if the caller doesn't have the given
+ * permission
+ */
+ void enforcePermission(String permission, String message) throws SecurityException;
+
+ /**
+ * Returns the package name of the reference package defined in 'overlay-config-signature' tag
+ * of SystemConfig. This package is vetted on scan by PackageManagerService that it's a system
+ * package and is used to check if overlay matches its signature in order to fulfill the
+ * config_signature policy.
+ */
+ @Nullable
+ String getConfigSignaturePackage();
+
+ /**
+ * @return map of system pre-defined, uniquely named actors; keys are namespace,
+ * value maps actor name to package name
+ */
+ @NonNull
+ Map<String, Map<String, String>> getNamedActors();
+
+ /**
+ * @see PackageManagerInternal#getOverlayPackages(int)
+ */
+ List<PackageInfo> getOverlayPackages(int userId);
+
+ /**
+ * Read from the APK and AndroidManifest of a package to return the overlayable defined for
+ * a given name.
+ *
+ * @throws IOException if the target can't be read
+ */
+ @Nullable
+ OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
+ @NonNull String targetOverlayableName, int userId)
+ throws IOException;
+
+ /**
+ * @see PackageManager#getPackagesForUid(int)
+ */
+ @Nullable
+ String[] getPackagesForUid(int uid);
+
+ /**
+ * @param userId user to filter package visibility by
+ * @see PackageManager#getPackageInfo(String, int)
+ */
+ @Nullable
PackageInfo getPackageInfo(@NonNull String packageName, int userId);
+
+ /**
+ * @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
+ * in the system returns {@link PackageManager#SIGNATURE_MATCH}
+ */
boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
- List<PackageInfo> getOverlayPackages(int userId);
}
diff --git a/services/core/java/com/android/server/os/TEST_MAPPING b/services/core/java/com/android/server/os/TEST_MAPPING
index a837fb4184ba..d937af1e3fdb 100644
--- a/services/core/java/com/android/server/os/TEST_MAPPING
+++ b/services/core/java/com/android/server/os/TEST_MAPPING
@@ -1,6 +1,14 @@
{
"presubmit": [
- // TODO(159590499) add BugreportManagerTestCases
+ {
+ "file_patterns": ["Bugreport[^/]*\\.java"],
+ "name": "BugreportManagerTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ },
{
"file_patterns": ["Bugreport[^/]*\\.java"],
"name": "CtsBugreportTestCases",
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index c3c2e5e65103..92c0c6af17d4 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -137,11 +137,11 @@ public class AppsFilter {
@VisibleForTesting(visibility = PRIVATE)
AppsFilter(StateProvider stateProvider,
FeatureConfig featureConfig,
- String[] forceQueryableWhitelist,
+ String[] forceQueryableList,
boolean systemAppsQueryable,
@Nullable OverlayReferenceMapper.Provider overlayProvider) {
mFeatureConfig = featureConfig;
- mForceQueryableByDevicePackageNames = forceQueryableWhitelist;
+ mForceQueryableByDevicePackageNames = forceQueryableList;
mSystemAppsQueryable = systemAppsQueryable;
mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/,
overlayProvider);
@@ -746,11 +746,11 @@ public class AppsFilter {
* @param users the set of users that should be evaluated for this calculation
* @param existingSettings the set of all package settings that currently exist on device
* @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
- * provided setting or null if the app is visible to all and no whitelist should be
+ * provided setting or null if the app is visible to all and no allow list should be
* applied.
*/
@Nullable
- public SparseArray<int[]> getVisibilityWhitelist(PackageSetting setting, int[] users,
+ public SparseArray<int[]> getVisibilityAllowList(PackageSetting setting, int[] users,
ArrayMap<String, PackageSetting> existingSettings) {
if (mForceQueryable.contains(setting.appId)) {
return null;
@@ -761,14 +761,14 @@ public class AppsFilter {
final int userId = users[u];
int[] appIds = new int[existingSettings.size()];
int[] buffer = null;
- int whitelistSize = 0;
+ int allowListSize = 0;
for (int i = existingSettings.size() - 1; i >= 0; i--) {
final PackageSetting existingSetting = existingSettings.valueAt(i);
final int existingAppId = existingSetting.appId;
if (existingAppId < Process.FIRST_APPLICATION_UID) {
continue;
}
- final int loc = Arrays.binarySearch(appIds, 0, whitelistSize, existingAppId);
+ final int loc = Arrays.binarySearch(appIds, 0, allowListSize, existingAppId);
if (loc >= 0) {
continue;
}
@@ -778,13 +778,13 @@ public class AppsFilter {
buffer = new int[appIds.length];
}
final int insert = ~loc;
- System.arraycopy(appIds, insert, buffer, 0, whitelistSize - insert);
+ System.arraycopy(appIds, insert, buffer, 0, allowListSize - insert);
appIds[insert] = existingAppId;
- System.arraycopy(buffer, 0, appIds, insert + 1, whitelistSize - insert);
- whitelistSize++;
+ System.arraycopy(buffer, 0, appIds, insert + 1, allowListSize - insert);
+ allowListSize++;
}
}
- result.put(userId, Arrays.copyOf(appIds, whitelistSize));
+ result.put(userId, Arrays.copyOf(appIds, allowListSize));
}
return result;
}
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 5415967c3bdc..d48570fa3b0f 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -337,6 +337,7 @@ public class BackgroundDexOptService extends JobService {
private int idleOptimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
long lowStorageThreshold) {
ArraySet<String> updatedPackages = new ArraySet<>();
+ ArraySet<String> updatedPackagesDueToSecondaryDex = new ArraySet<>();
try {
final boolean supportSecondaryDex = supportSecondaryDex();
@@ -391,11 +392,14 @@ public class BackgroundDexOptService extends JobService {
}
int secondaryResult = optimizePackages(pm, pkgs, lowStorageThreshold,
- /*isForPrimaryDex*/ false, updatedPackages);
+ /*isForPrimaryDex*/ false, updatedPackagesDueToSecondaryDex);
return secondaryResult;
} finally {
// Always let the pinner service know about changes.
notifyPinService(updatedPackages);
+ // Only notify IORap the primary dex opt, because we don't want to
+ // invalidate traces unnecessary due to b/161633001 and that it's
+ // better to have a trace than no trace at all.
notifyPackagesUpdated(updatedPackages);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 312dcddd577d..55e7ca8ca838 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1284,10 +1284,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
int N = mSessions.size();
for (int i = 0; i < N; i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
- if (session.isStagedAndInTerminalState()) {
+
+ // Do not print finalized staged session as active install sessions
+ final PackageInstallerSession rootSession = session.hasParentSessionId()
+ ? getSession(session.getParentSessionId())
+ : session;
+ if (rootSession.isStagedAndInTerminalState()) {
finalizedSessions.add(session);
continue;
}
+
session.dump(pw);
pw.println();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 92da005babfa..7765f18300fe 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -157,6 +157,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@@ -262,6 +263,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private final Object mLock = new Object();
+ /**
+ * Used to detect and reject concurrent access to this session object to ensure mutation
+ * to multiple objects like {@link #addChildSessionId} are done atomically.
+ */
+ private final AtomicBoolean mTransactionLock = new AtomicBoolean(false);
+
/** Timestamp of the last time this session changed state */
@GuardedBy("mLock")
private long updatedMillis;
@@ -1746,7 +1753,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
try {
- installNonStaged(childSessions);
+ verifyNonStaged(childSessions);
} catch (PackageManagerException e) {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
@@ -1755,23 +1762,64 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
+ private void verifyNonStaged(List<PackageInstallerSession> childSessions)
+ throws PackageManagerException {
+ final PackageManagerService.VerificationParams verifyingSession =
+ makeVerificationParams();
+ if (verifyingSession == null) {
+ return;
+ }
+ if (isMultiPackage()) {
+ List<PackageManagerService.VerificationParams> verifyingChildSessions =
+ new ArrayList<>(childSessions.size());
+ boolean success = true;
+ PackageManagerException failure = null;
+ for (int i = 0; i < childSessions.size(); ++i) {
+ final PackageInstallerSession session = childSessions.get(i);
+ try {
+ final PackageManagerService.VerificationParams verifyingChildSession =
+ session.makeVerificationParams();
+ if (verifyingChildSession != null) {
+ verifyingChildSessions.add(verifyingChildSession);
+ }
+ } catch (PackageManagerException e) {
+ failure = e;
+ success = false;
+ }
+ }
+ if (!success) {
+ final IntentSender statusReceiver;
+ synchronized (mLock) {
+ statusReceiver = mRemoteStatusReceiver;
+ }
+ sendOnPackageInstalled(mContext, statusReceiver, sessionId,
+ isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId, null,
+ failure.error, failure.getLocalizedMessage(), null);
+ return;
+ }
+ mPm.verifyStage(verifyingSession, verifyingChildSessions);
+ } else {
+ mPm.verifyStage(verifyingSession);
+ }
+ }
+
private void installNonStaged(List<PackageInstallerSession> childSessions)
throws PackageManagerException {
- final PackageManagerService.ActiveInstallSession installingSession =
- makeSessionActive();
+ final PackageManagerService.InstallParams installingSession =
+ makeInstallParams();
if (installingSession == null) {
return;
}
if (isMultiPackage()) {
- List<PackageManagerService.ActiveInstallSession> installingChildSessions =
+ List<PackageManagerService.InstallParams> installingChildSessions =
new ArrayList<>(childSessions.size());
boolean success = true;
PackageManagerException failure = null;
for (int i = 0; i < childSessions.size(); ++i) {
final PackageInstallerSession session = childSessions.get(i);
try {
- final PackageManagerService.ActiveInstallSession installingChildSession =
- session.makeSessionActive();
+ final PackageManagerService.InstallParams installingChildSession =
+ session.makeInstallParams();
if (installingChildSession != null) {
installingChildSessions.add(installingChildSession);
}
@@ -1797,11 +1845,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
/**
- * Stages this session for install and returns a
- * {@link PackageManagerService.ActiveInstallSession} representing this new staged state or null
- * in case permissions need to be requested before install can proceed.
+ * Stages this session for verification and returns a
+ * {@link PackageManagerService.VerificationParams} representing this new staged state or null
+ * in case permissions need to be requested before verification can proceed.
*/
- private PackageManagerService.ActiveInstallSession makeSessionActive()
+ @Nullable
+ private PackageManagerService.VerificationParams makeVerificationParams()
throws PackageManagerException {
assertNotLocked("makeSessionActive");
@@ -1820,6 +1869,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
+ // TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc
if (!params.isMultiPackage && needToAskForPermissions()) {
// User needs to confirm installation;
// give installer an intent they can use to involve
@@ -1841,12 +1891,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
synchronized (mLock) {
- return makeSessionActiveLocked();
+ return makeVerificationParamsLocked();
}
}
@GuardedBy("mLock")
- private PackageManagerService.ActiveInstallSession makeSessionActiveLocked()
+ private PackageManagerService.VerificationParams makeVerificationParamsLocked()
throws PackageManagerException {
if (!params.isMultiPackage) {
Objects.requireNonNull(mPackageName);
@@ -1910,29 +1960,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
}
- // We've reached point of no return; call into PMS to install the stage.
- // Regardless of success or failure we always destroy session.
- final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
- @Override
- public void onUserActionRequired(Intent intent) {
- throw new IllegalStateException();
- }
-
- @Override
- public void onPackageInstalled(String basePackageName, int returnCode, String msg,
- Bundle extras) {
- destroyInternal();
- dispatchSessionFinished(returnCode, msg, extras);
- }
- };
-
- // An observer through which PMS returns the result of verification
- // TODO(samiul): We are temporarily assigning two observer to ActiveInstallSession. One for
- // installation and one for verification. This will be fixed within next few CLs.
- final IPackageInstallObserver2 sessionVerificationObserver;
+ final IPackageInstallObserver2 localObserver;
if (!hasParentSessionId()) {
// Avoid attaching this observer to child session since they won't use it.
- sessionVerificationObserver = new IPackageInstallObserver2.Stub() {
+ localObserver = new IPackageInstallObserver2.Stub() {
@Override
public void onUserActionRequired(Intent intent) {
throw new IllegalStateException();
@@ -1942,16 +1973,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
- // TODO(samiul): In future, packages will not be installed immediately after
- // verification. Package verification will return control back to here,
- // and we will have call into PMS again to install package.
- //
- // For now, this is a no op.
+ onVerificationComplete();
+ } else {
+ destroyInternal();
+ dispatchSessionFinished(returnCode, msg, extras);
}
}
};
} else {
- sessionVerificationObserver = null;
+ localObserver = null;
}
final UserHandle user;
@@ -1962,9 +1992,73 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
mRelinquished = true;
- return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver,
- sessionVerificationObserver, sessionId, params, mInstallerUid, mInstallSource, user,
- mSigningDetails);
+
+ return mPm.new VerificationParams(user, stageDir, localObserver, params,
+ mInstallSource, mInstallerUid, mSigningDetails, sessionId);
+ }
+
+ private void onVerificationComplete() {
+ if ((params.installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
+ destroyInternal();
+ dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Dry run", new Bundle());
+ return;
+ }
+
+ List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
+ try {
+ installNonStaged(childSessions);
+ } catch (PackageManagerException e) {
+ final String completeMsg = ExceptionUtils.getCompleteMessage(e);
+ Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
+ destroyInternal();
+ dispatchSessionFinished(e.error, completeMsg, null);
+ }
+ }
+
+ /**
+ * Stages this session for install and returns a
+ * {@link PackageManagerService.InstallParams} representing this new staged state.
+ */
+ private PackageManagerService.InstallParams makeInstallParams()
+ throws PackageManagerException {
+ synchronized (mLock) {
+ if (mDestroyed) {
+ throw new PackageManagerException(
+ INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed");
+ }
+ if (!mSealed) {
+ throw new PackageManagerException(
+ INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed");
+ }
+ }
+
+ // We've reached point of no return; call into PMS to install the stage.
+ // Regardless of success or failure we always destroy session.
+ final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
+ @Override
+ public void onUserActionRequired(Intent intent) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+ Bundle extras) {
+ destroyInternal();
+ dispatchSessionFinished(returnCode, msg, extras);
+ }
+ };
+
+ final UserHandle user;
+ if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
+ user = UserHandle.ALL;
+ } else {
+ user = new UserHandle(userId);
+ }
+
+ synchronized (mLock) {
+ return mPm.new InstallParams(stageDir, localObserver, params, mInstallSource, user,
+ mSigningDetails, mInstallerUid);
+ }
}
private static void maybeRenameFile(File from, File to) throws PackageManagerException {
@@ -3073,39 +3167,85 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
+ private void acquireTransactionLock() {
+ if (!mTransactionLock.compareAndSet(false, true)) {
+ throw new UnsupportedOperationException("Concurrent access not supported");
+ }
+ }
+
+ private void releaseTransactionLock() {
+ mTransactionLock.compareAndSet(true, false);
+ }
+
@Override
public void addChildSessionId(int childSessionId) {
+ if (!params.isMultiPackage) {
+ throw new IllegalStateException("Single-session " + sessionId + " can't have child.");
+ }
+
final PackageInstallerSession childSession = mSessionProvider.getSession(childSessionId);
- if (childSession == null || !childSession.canBeAddedAsChild(sessionId)) {
+ if (childSession == null) {
throw new IllegalStateException("Unable to add child session " + childSessionId
- + " as it does not exist or is in an invalid state.");
+ + " as it does not exist.");
+ }
+ if (childSession.params.isMultiPackage) {
+ throw new IllegalStateException("Multi-session " + childSessionId
+ + " can't be a child.");
}
- synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
- assertPreparedAndNotSealedLocked("addChildSessionId");
- final int indexOfSession = mChildSessionIds.indexOfKey(childSessionId);
- if (indexOfSession >= 0) {
- return;
+ try {
+ acquireTransactionLock();
+ childSession.acquireTransactionLock();
+
+ if (!childSession.canBeAddedAsChild(sessionId)) {
+ throw new IllegalStateException("Unable to add child session " + childSessionId
+ + " as it is in an invalid state.");
}
- childSession.setParentSessionId(this.sessionId);
- addChildSessionIdLocked(childSessionId);
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotSealedLocked("addChildSessionId");
+
+ final int indexOfSession = mChildSessionIds.indexOfKey(childSessionId);
+ if (indexOfSession >= 0) {
+ return;
+ }
+ childSession.setParentSessionId(this.sessionId);
+ addChildSessionIdLocked(childSessionId);
+ }
+ } finally {
+ releaseTransactionLock();
+ childSession.releaseTransactionLock();
}
}
@Override
public void removeChildSessionId(int sessionId) {
final PackageInstallerSession session = mSessionProvider.getSession(sessionId);
- synchronized (mLock) {
- final int indexOfSession = mChildSessionIds.indexOfKey(sessionId);
+ try {
+ acquireTransactionLock();
if (session != null) {
- session.setParentSessionId(SessionInfo.INVALID_ID);
+ session.acquireTransactionLock();
}
- if (indexOfSession < 0) {
- // not added in the first place; no-op
- return;
+
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotSealedLocked("removeChildSessionId");
+
+ final int indexOfSession = mChildSessionIds.indexOfKey(sessionId);
+ if (indexOfSession < 0) {
+ // not added in the first place; no-op
+ return;
+ }
+ if (session != null) {
+ session.setParentSessionId(SessionInfo.INVALID_ID);
+ }
+ mChildSessionIds.removeAt(indexOfSession);
+ }
+ } finally {
+ releaseTransactionLock();
+ if (session != null) {
+ session.releaseTransactionLock();
}
- mChildSessionIds.removeAt(indexOfSession);
}
}
@@ -3260,7 +3400,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private void destroyInternal() {
synchronized (mLock) {
mSealed = true;
- if (!params.isStaged || isStagedAndInTerminalState()) {
+ if (!params.isStaged) {
mDestroyed = true;
}
// Force shut down all bridges
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 73db48a4939e..a726c8d26b98 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -120,6 +120,7 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
+import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
@@ -331,6 +332,7 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
+import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.server.AttributeCache;
import com.android.server.DeviceIdleInternal;
import com.android.server.EventLogTags;
@@ -1127,6 +1129,7 @@ public class PackageManagerService extends IPackageManager.Stub
public @Nullable String storageManagerPackage;
public @Nullable String defaultTextClassifierPackage;
public @Nullable String systemTextClassifierPackage;
+ public @Nullable String overlayConfigSignaturePackage;
public ViewCompiler viewCompiler;
public @Nullable String wellbeingPackage;
public @Nullable String retailDemoPackage;
@@ -1159,7 +1162,7 @@ public class PackageManagerService extends IPackageManager.Stub
final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();
/** List of packages waiting for rollback to be enabled. */
- final SparseArray<InstallParams> mPendingEnableRollback = new SparseArray<>();
+ final SparseArray<VerificationParams> mPendingEnableRollback = new SparseArray<>();
final PackageInstallerService mInstallerService;
@@ -1659,6 +1662,7 @@ public class PackageManagerService extends IPackageManager.Stub
final @Nullable String mServicesExtensionPackageName;
final @Nullable String mSharedSystemSharedLibraryPackageName;
final @Nullable String mRetailDemoPackage;
+ final @Nullable String mOverlayConfigSignaturePackage;
private final PackageUsage mPackageUsage = new PackageUsage();
private final CompilerStats mCompilerStats = new CompilerStats();
@@ -1833,7 +1837,7 @@ public class PackageManagerService extends IPackageManager.Stub
if ((state != null) && !state.isVerificationComplete()
&& !state.timeoutExtended()) {
- final InstallParams params = state.getInstallParams();
+ final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
Slog.i(TAG, "Verification timed out for " + originUri);
@@ -1874,7 +1878,7 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageVerificationState state = mPendingVerification.get(verificationId);
if (state != null && !state.isIntegrityVerificationComplete()) {
- final InstallParams params = state.getInstallParams();
+ final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
Slog.i(TAG, "Integrity verification timed out for " + originUri);
@@ -1919,7 +1923,7 @@ public class PackageManagerService extends IPackageManager.Stub
state.setVerifierResponse(response.callerUid, response.code);
if (state.isVerificationComplete()) {
- final InstallParams params = state.getInstallParams();
+ final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
if (state.isInstallAllowed()) {
@@ -1953,7 +1957,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final int response = (Integer) msg.obj;
- final InstallParams params = state.getInstallParams();
+ final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
state.setIntegrityVerificationResult(response);
@@ -2037,7 +2041,8 @@ public class PackageManagerService extends IPackageManager.Stub
case ENABLE_ROLLBACK_STATUS: {
final int enableRollbackToken = msg.arg1;
final int enableRollbackCode = msg.arg2;
- InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
+ final VerificationParams params =
+ mPendingEnableRollback.get(enableRollbackToken);
if (params == null) {
Slog.w(TAG, "Invalid rollback enabled token "
+ enableRollbackToken + " received");
@@ -2061,7 +2066,8 @@ public class PackageManagerService extends IPackageManager.Stub
case ENABLE_ROLLBACK_TIMEOUT: {
final int enableRollbackToken = msg.arg1;
final int sessionId = msg.arg2;
- final InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
+ final VerificationParams params =
+ mPendingEnableRollback.get(enableRollbackToken);
if (params != null) {
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
@@ -2210,17 +2216,17 @@ public class PackageManagerService extends IPackageManager.Stub
}
extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
// Send to all running apps.
- final SparseArray<int[]> newBroadcastWhitelist;
+ final SparseArray<int[]> newBroadcastAllowList;
synchronized (mLock) {
- newBroadcastWhitelist = mAppsFilter.getVisibilityWhitelist(
+ newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
getPackageSettingInternal(res.name, Process.SYSTEM_UID),
updateUserIds, mSettings.mPackages);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
extras, 0 /*flags*/,
null /*targetPackage*/, null /*finishedReceiver*/,
- updateUserIds, instantUserIds, newBroadcastWhitelist);
+ updateUserIds, instantUserIds, newBroadcastAllowList);
if (installerPackageName != null) {
// Send to the installer, even if it's not running.
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
@@ -2252,7 +2258,7 @@ public class PackageManagerService extends IPackageManager.Stub
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
packageName, extras, 0 /*flags*/,
null /*targetPackage*/, null /*finishedReceiver*/,
- updateUserIds, instantUserIds, res.removedInfo.broadcastWhitelist);
+ updateUserIds, instantUserIds, res.removedInfo.broadcastAllowList);
if (installerPackageName != null) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
extras, 0 /*flags*/,
@@ -2588,7 +2594,7 @@ public class PackageManagerService extends IPackageManager.Stub
(i, pm) ->
new Settings(Environment.getDataDirectory(),
i.getPermissionManagerServiceInternal().getPermissionSettings(),
- lock),
+ RuntimePermissionsPersistence.createInstance(), lock),
new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class),
new Injector.LocalServicesProducer<>(ActivityManagerInternal.class),
new Injector.LocalServicesProducer<>(DeviceIdleInternal.class),
@@ -2814,6 +2820,7 @@ public class PackageManagerService extends IPackageManager.Stub
mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
+ mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
mResolveComponentName = testParams.resolveComponentName;
mPackages.putAll(testParams.packages);
@@ -3379,6 +3386,7 @@ public class PackageManagerService extends IPackageManager.Stub
mAppPredictionServicePackage = getAppPredictionServicePackageName();
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
mRetailDemoPackage = getRetailDemoPackageName();
+ mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths.
@@ -4205,13 +4213,9 @@ public class PackageManagerService extends IPackageManager.Stub
Iterator<ResolveInfo> iter = matches.iterator();
while (iter.hasNext()) {
final ResolveInfo rInfo = iter.next();
- final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
- if (ps != null) {
- final PermissionsState permissionsState = ps.getPermissionsState();
- if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
- || Build.IS_ENG) {
- continue;
- }
+ if (checkPermission(Manifest.permission.INSTALL_PACKAGES,
+ rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) {
+ continue;
}
iter.remove();
}
@@ -8591,10 +8595,9 @@ public class PackageManagerService extends IPackageManager.Stub
private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
String[] permissions, boolean[] tmp, int flags, int userId) {
int numMatch = 0;
- final PermissionsState permissionsState = ps.getPermissionsState();
for (int i=0; i<permissions.length; i++) {
final String permission = permissions[i];
- if (permissionsState.hasPermission(permission, userId)) {
+ if (checkPermission(permission, ps.name, userId) == PERMISSION_GRANTED) {
tmp[i] = true;
numMatch++;
} else {
@@ -12119,12 +12122,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
// Exempt SharedUsers signed with the platform key.
PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
- if ((platformPkgSetting.signatures.mSigningDetails
- != PackageParser.SigningDetails.UNKNOWN)
- && (compareSignatures(
- platformPkgSetting.signatures.mSigningDetails.signatures,
- pkg.getSigningDetails().signatures)
- != PackageManager.SIGNATURE_MATCH)) {
+ if (!comparePackageSignatures(platformPkgSetting,
+ pkg.getSigningDetails().signatures)) {
throw new PackageManagerException("Apps that share a user with a " +
"privileged app must themselves be marked as privileged. " +
pkg.getPackageName() + " shares privileged user " +
@@ -12171,12 +12170,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
final PackageSetting platformPkgSetting =
mSettings.getPackageLPr("android");
- if ((platformPkgSetting.signatures.mSigningDetails
- != PackageParser.SigningDetails.UNKNOWN)
- && (compareSignatures(
- platformPkgSetting.signatures.mSigningDetails.signatures,
- pkg.getSigningDetails().signatures)
- != PackageManager.SIGNATURE_MATCH)) {
+ if (!comparePackageSignatures(platformPkgSetting,
+ pkg.getSigningDetails().signatures)) {
throw new PackageManagerException("Overlay "
+ pkg.getPackageName()
+ " must target Q or later, "
@@ -12185,24 +12180,35 @@ public class PackageManagerService extends IPackageManager.Stub
}
// A non-preloaded overlay package, without <overlay android:targetName>, will
- // only be used if it is signed with the same certificate as its target. If the
- // target is already installed, check this here to augment the last line of
- // defence which is OMS.
+ // only be used if it is signed with the same certificate as its target OR if
+ // it is signed with the same certificate as a reference package declared
+ // in 'config-signature' tag of SystemConfig.
+ // If the target is already installed or 'config-signature' tag in SystemConfig
+ // is set, check this here to augment the last line of defence which is OMS.
if (pkg.getOverlayTargetName() == null) {
final PackageSetting targetPkgSetting =
mSettings.getPackageLPr(pkg.getOverlayTarget());
if (targetPkgSetting != null) {
- if ((targetPkgSetting.signatures.mSigningDetails
- != PackageParser.SigningDetails.UNKNOWN)
- && (compareSignatures(
- targetPkgSetting.signatures.mSigningDetails.signatures,
- pkg.getSigningDetails().signatures)
- != PackageManager.SIGNATURE_MATCH)) {
- throw new PackageManagerException("Overlay "
- + pkg.getPackageName() + " and target "
- + pkg.getOverlayTarget() + " signed with"
- + " different certificates, and the overlay lacks"
- + " <overlay android:targetName>");
+ if (!comparePackageSignatures(targetPkgSetting,
+ pkg.getSigningDetails().signatures)) {
+ // check reference signature
+ if (mOverlayConfigSignaturePackage == null) {
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName() + " and target "
+ + pkg.getOverlayTarget() + " signed with"
+ + " different certificates, and the overlay lacks"
+ + " <overlay android:targetName>");
+ }
+ final PackageSetting refPkgSetting =
+ mSettings.getPackageLPr(mOverlayConfigSignaturePackage);
+ if (!comparePackageSignatures(refPkgSetting,
+ pkg.getSigningDetails().signatures)) {
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName() + " signed with a different "
+ + "certificate than both the reference package and "
+ + "target " + pkg.getOverlayTarget() + ", and the "
+ + "overlay lacks <overlay android:targetName>");
+ }
}
}
}
@@ -12672,7 +12678,7 @@ public class PackageManagerService extends IPackageManager.Stub
public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
final int[] userIds, int[] instantUserIds,
- @Nullable SparseArray<int[]> broadcastWhitelist) {
+ @Nullable SparseArray<int[]> broadcastAllowList) {
mHandler.post(() -> {
try {
final IActivityManager am = ActivityManager.getService();
@@ -12684,7 +12690,7 @@ public class PackageManagerService extends IPackageManager.Stub
resolvedUserIds = userIds;
}
doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
- resolvedUserIds, false, broadcastWhitelist);
+ resolvedUserIds, false, broadcastAllowList);
if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
instantUserIds, true, null);
@@ -12757,7 +12763,7 @@ public class PackageManagerService extends IPackageManager.Stub
*/
private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
int flags, String targetPkg, IIntentReceiver finishedReceiver,
- int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastWhitelist) {
+ int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList) {
for (int id : userIds) {
final Intent intent = new Intent(action,
pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
@@ -12787,7 +12793,7 @@ public class PackageManagerService extends IPackageManager.Stub
mInjector.getActivityManagerInternal().broadcastIntent(
intent, finishedReceiver, requiredPermissions,
finishedReceiver != null, id,
- broadcastWhitelist == null ? null : broadcastWhitelist.get(id));
+ broadcastAllowList == null ? null : broadcastAllowList.get(id));
}
}
@@ -12850,15 +12856,8 @@ public class PackageManagerService extends IPackageManager.Stub
return installReason;
}
- void installStage(ActiveInstallSession activeInstallSession) {
- if (DEBUG_INSTANT) {
- if ((activeInstallSession.getSessionParams().installFlags
- & PackageManager.INSTALL_INSTANT_APP) != 0) {
- Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
- }
- }
+ void installStage(InstallParams params) {
final Message msg = mHandler.obtainMessage(INIT_COPY);
- final InstallParams params = new InstallParams(activeInstallSession);
params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
@@ -12870,11 +12869,11 @@ public class PackageManagerService extends IPackageManager.Stub
mHandler.sendMessage(msg);
}
- void installStage(ActiveInstallSession parent, List<ActiveInstallSession> children)
+ void installStage(InstallParams parent, List<InstallParams> children)
throws PackageManagerException {
final Message msg = mHandler.obtainMessage(INIT_COPY);
final MultiPackageInstallParams params =
- new MultiPackageInstallParams(UserHandle.ALL, parent, children);
+ new MultiPackageInstallParams(parent, children);
params.setTraceMethod("installStageMultiPackage")
.setTraceCookie(System.identityHashCode(params));
msg.obj = params;
@@ -12886,6 +12885,21 @@ public class PackageManagerService extends IPackageManager.Stub
mHandler.sendMessage(msg);
}
+ void verifyStage(VerificationParams params) {
+ mHandler.post(()-> {
+ params.startCopy();
+ });
+ }
+
+ void verifyStage(VerificationParams parent, List<VerificationParams> children)
+ throws PackageManagerException {
+ final MultiPackageVerificationParams params =
+ new MultiPackageVerificationParams(parent, children);
+ mHandler.post(()-> {
+ params.startCopy();
+ });
+ }
+
private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
int userId, int dataLoaderType) {
final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
@@ -12919,7 +12933,7 @@ public class PackageManagerService extends IPackageManager.Stub
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, 0, null, null, userIds, instantUserIds,
- mAppsFilter.getVisibilityWhitelist(
+ mAppsFilter.getVisibilityAllowList(
getPackageSettingInternal(packageName, Process.SYSTEM_UID),
userIds, mSettings.mPackages));
if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
@@ -14746,32 +14760,21 @@ public class PackageManagerService extends IPackageManager.Stub
* committed together.
*/
class MultiPackageInstallParams extends HandlerParams {
- private final IPackageInstallObserver2 mVerificationObserver;
- @NonNull
- private final ArrayList<InstallParams> mChildParams;
- // TODO(samiul): mCurrentState will relocated to a install-specific class in future
- @NonNull
+ private final List<InstallParams> mChildParams;
private final Map<InstallArgs, Integer> mCurrentState;
- private final Map<InstallParams, Integer> mVerificationState;
- MultiPackageInstallParams(
- @NonNull UserHandle user,
- @NonNull ActiveInstallSession parent,
- @NonNull List<ActiveInstallSession> activeInstallSessions)
+ MultiPackageInstallParams(InstallParams parent, List<InstallParams> childParams)
throws PackageManagerException {
- super(user);
- if (activeInstallSessions.size() == 0) {
+ super(parent.getUser());
+ if (childParams.size() == 0) {
throw new PackageManagerException("No child sessions found!");
}
- mChildParams = new ArrayList<>(activeInstallSessions.size());
- for (int i = 0; i < activeInstallSessions.size(); i++) {
- final InstallParams childParams = new InstallParams(activeInstallSessions.get(i));
- childParams.mParentInstallParams = this;
- this.mChildParams.add(childParams);
+ mChildParams = childParams;
+ for (int i = 0; i < childParams.size(); i++) {
+ final InstallParams childParam = childParams.get(i);
+ childParam.mParentInstallParams = this;
}
this.mCurrentState = new ArrayMap<>(mChildParams.size());
- this.mVerificationState = new ArrayMap<>(mChildParams.size());
- mVerificationObserver = parent.getVerificationObserver();
}
@Override
@@ -14788,7 +14791,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- // TODO(samiul): this method will relocated to a install-specific class in future
void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
mCurrentState.put(args, currentStatus);
if (mCurrentState.size() != mChildParams.size()) {
@@ -14812,122 +14814,67 @@ public class PackageManagerService extends IPackageManager.Stub
completeStatus == PackageManager.INSTALL_SUCCEEDED,
installRequests);
}
-
- void trySendVerificationCompleteNotification(InstallParams child, int currentStatus) {
- mVerificationState.put(child, currentStatus);
- if (mVerificationState.size() != mChildParams.size()) {
- return;
- }
- int completeStatus = PackageManager.INSTALL_SUCCEEDED;
- for (Integer status : mVerificationState.values()) {
- if (status == PackageManager.INSTALL_UNKNOWN) {
- return;
- } else if (status != PackageManager.INSTALL_SUCCEEDED) {
- completeStatus = status;
- break;
- }
- }
- try {
- mVerificationObserver.onPackageInstalled(null, completeStatus,
- "Package Verification Result", new Bundle());
- } catch (RemoteException e) {
- Slog.i(TAG, "Observer no longer exists.");
- }
- }
}
class InstallParams extends HandlerParams {
- // TODO: see if we can collapse this into ActiveInstallSession
-
final OriginInfo origin;
final MoveInfo move;
- final IPackageInstallObserver2 mInstallObserver;
- private final IPackageInstallObserver2 mVerificationObserver;
+ final IPackageInstallObserver2 observer;
int installFlags;
@NonNull final InstallSource installSource;
final String volumeUuid;
- private boolean mWaitForVerificationToComplete;
- private boolean mWaitForIntegrityVerificationToComplete;
- private boolean mWaitForEnableRollbackToComplete;
int mRet;
final String packageAbiOverride;
final String[] grantedRuntimePermissions;
final List<String> whitelistedRestrictedPermissions;
final int autoRevokePermissionsMode;
- final VerificationInfo verificationInfo;
final PackageParser.SigningDetails signingDetails;
final int installReason;
- @Nullable
- MultiPackageInstallParams mParentInstallParams;
- final long requiredInstalledVersionCode;
+ @Nullable MultiPackageInstallParams mParentInstallParams;
final boolean forceQueryableOverride;
final int mDataLoaderType;
- final int mSessionId;
- InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 installObserver,
+ InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
int installFlags, InstallSource installSource, String volumeUuid,
- VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
- String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
- int autoRevokePermissionsMode,
- SigningDetails signingDetails, int installReason,
- long requiredInstalledVersionCode, int dataLoaderType) {
+ UserHandle user, String packageAbiOverride) {
super(user);
this.origin = origin;
this.move = move;
- this.mInstallObserver = installObserver;
- this.mVerificationObserver = null;
+ this.observer = observer;
this.installFlags = installFlags;
this.installSource = Preconditions.checkNotNull(installSource);
this.volumeUuid = volumeUuid;
- this.verificationInfo = verificationInfo;
this.packageAbiOverride = packageAbiOverride;
- this.grantedRuntimePermissions = grantedPermissions;
- this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
- this.autoRevokePermissionsMode = autoRevokePermissionsMode;
- this.signingDetails = signingDetails;
- this.installReason = installReason;
- this.requiredInstalledVersionCode = requiredInstalledVersionCode;
+
+ this.grantedRuntimePermissions = null;
+ this.whitelistedRestrictedPermissions = null;
+ this.autoRevokePermissionsMode = MODE_DEFAULT;
+ this.signingDetails = PackageParser.SigningDetails.UNKNOWN;
+ this.installReason = PackageManager.INSTALL_REASON_UNKNOWN;
this.forceQueryableOverride = false;
- this.mDataLoaderType = dataLoaderType;
- this.mSessionId = -1;
+ this.mDataLoaderType = DataLoaderType.NONE;
}
- InstallParams(ActiveInstallSession activeInstallSession) {
- super(activeInstallSession.getUser());
- final PackageInstaller.SessionParams sessionParams =
- activeInstallSession.getSessionParams();
- if (DEBUG_INSTANT) {
- if ((sessionParams.installFlags
- & PackageManager.INSTALL_INSTANT_APP) != 0) {
- Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
- }
- }
- verificationInfo = new VerificationInfo(
- sessionParams.originatingUri,
- sessionParams.referrerUri,
- sessionParams.originatingUid,
- activeInstallSession.getInstallerUid());
- origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
+ InstallParams(File stagedDir, IPackageInstallObserver2 observer,
+ PackageInstaller.SessionParams sessionParams, InstallSource installSource,
+ UserHandle user, SigningDetails signingDetails, int installerUid) {
+ super(user);
+ origin = OriginInfo.fromStagedFile(stagedDir);
move = null;
installReason = fixUpInstallReason(
- activeInstallSession.getInstallSource().installerPackageName,
- activeInstallSession.getInstallerUid(),
- sessionParams.installReason);
- mInstallObserver = activeInstallSession.getInstallObserver();
- mVerificationObserver = activeInstallSession.getVerificationObserver();
+ installSource.installerPackageName, installerUid, sessionParams.installReason);
+ this.observer = observer;
installFlags = sessionParams.installFlags;
- installSource = activeInstallSession.getInstallSource();
+ this.installSource = installSource;
volumeUuid = sessionParams.volumeUuid;
packageAbiOverride = sessionParams.abiOverride;
grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
autoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
- signingDetails = activeInstallSession.getSigningDetails();
- requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
+ this.signingDetails = signingDetails;
forceQueryableOverride = sessionParams.forceQueryableOverride;
mDataLoaderType = (sessionParams.dataLoaderParams != null)
? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
- mSessionId = activeInstallSession.getSessionId();
}
@Override
@@ -15074,12 +15021,146 @@ public class PackageManagerService extends IPackageManager.Stub
public void handleStartCopy() {
PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
origin.resolvedPath, installFlags, packageAbiOverride);
+ mRet = overrideInstallLocation(pkgLite);
+ }
- mRet = verifyReplacingVersionCode(pkgLite);
+ @Override
+ void handleReturnCode() {
+ processPendingInstall();
+ }
- if (mRet == INSTALL_SUCCEEDED) {
- mRet = overrideInstallLocation(pkgLite);
+ private void processPendingInstall() {
+ InstallArgs args = createInstallArgs(this);
+ if (mRet == PackageManager.INSTALL_SUCCEEDED) {
+ mRet = args.copyApk();
}
+ if (mParentInstallParams != null) {
+ mParentInstallParams.tryProcessInstallRequest(args, mRet);
+ } else {
+ PackageInstalledInfo res = createPackageInstalledInfo(mRet);
+ processInstallRequestsAsync(
+ res.returnCode == PackageManager.INSTALL_SUCCEEDED,
+ Collections.singletonList(new InstallRequest(args, res)));
+
+ }
+ }
+ }
+
+ /**
+ * Container for a multi-package install which refers to all install sessions and args being
+ * committed together.
+ */
+ class MultiPackageVerificationParams extends HandlerParams {
+ private final IPackageInstallObserver2 mObserver;
+ private final List<VerificationParams> mChildParams;
+ private final Map<VerificationParams, Integer> mVerificationState;
+
+ MultiPackageVerificationParams(
+ VerificationParams parent,
+ List<VerificationParams> children)
+ throws PackageManagerException {
+ super(parent.getUser());
+ if (children.size() == 0) {
+ throw new PackageManagerException("No child sessions found!");
+ }
+ mChildParams = children;
+ // Provide every child with reference to this object as parent
+ for (int i = 0; i < children.size(); i++) {
+ final VerificationParams childParams = children.get(i);
+ childParams.mParentVerificationParams = this;
+ }
+ this.mVerificationState = new ArrayMap<>(mChildParams.size());
+ mObserver = parent.observer;
+ }
+
+ @Override
+ void handleStartCopy() {
+ for (VerificationParams params : mChildParams) {
+ params.handleStartCopy();
+ }
+ }
+
+ @Override
+ void handleReturnCode() {
+ for (VerificationParams params : mChildParams) {
+ params.handleReturnCode();
+ }
+ }
+
+ void trySendVerificationCompleteNotification(VerificationParams child, int currentStatus) {
+ mVerificationState.put(child, currentStatus);
+ if (mVerificationState.size() != mChildParams.size()) {
+ return;
+ }
+ int completeStatus = PackageManager.INSTALL_SUCCEEDED;
+ for (Integer status : mVerificationState.values()) {
+ if (status == PackageManager.INSTALL_UNKNOWN) {
+ return;
+ } else if (status != PackageManager.INSTALL_SUCCEEDED) {
+ completeStatus = status;
+ break;
+ }
+ }
+ try {
+ mObserver.onPackageInstalled(null, completeStatus,
+ "Package Verification Result", new Bundle());
+ } catch (RemoteException e) {
+ Slog.i(TAG, "Observer no longer exists.");
+ }
+ }
+ }
+
+ class VerificationParams extends HandlerParams {
+ final OriginInfo origin;
+ final IPackageInstallObserver2 observer;
+ final int installFlags;
+ @NonNull final InstallSource installSource;
+ final String packageAbiOverride;
+ final VerificationInfo verificationInfo;
+ final PackageParser.SigningDetails signingDetails;
+ @Nullable MultiPackageVerificationParams mParentVerificationParams;
+ final long requiredInstalledVersionCode;
+ final int mDataLoaderType;
+ final int mSessionId;
+
+ private boolean mWaitForVerificationToComplete;
+ private boolean mWaitForIntegrityVerificationToComplete;
+ private boolean mWaitForEnableRollbackToComplete;
+ private int mRet;
+
+ VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
+ PackageInstaller.SessionParams sessionParams, InstallSource installSource,
+ int installerUid, SigningDetails signingDetails, int sessionId) {
+ super(user);
+ origin = OriginInfo.fromStagedFile(stagedDir);
+ this.observer = observer;
+ installFlags = sessionParams.installFlags;
+ this.installSource = installSource;
+ packageAbiOverride = sessionParams.abiOverride;
+ verificationInfo = new VerificationInfo(
+ sessionParams.originatingUri,
+ sessionParams.referrerUri,
+ sessionParams.originatingUid,
+ installerUid
+ );
+ this.signingDetails = signingDetails;
+ requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
+ mDataLoaderType = (sessionParams.dataLoaderParams != null)
+ ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
+ mSessionId = sessionId;
+ }
+
+ @Override
+ public String toString() {
+ return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
+ + " file=" + origin.file + "}";
+ }
+
+ public void handleStartCopy() {
+ PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
+ origin.resolvedPath, installFlags, packageAbiOverride);
+
+ mRet = verifyReplacingVersionCode(pkgLite);
// Perform package verification and enable rollback (unless we are simply moving the
// package).
@@ -15242,7 +15323,7 @@ public class PackageManagerService extends IPackageManager.Stub
final long idleDuration = getVerificationTimeout();
idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
- idleDuration,
+ idleDuration,
false, "integrity component");
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setTemporaryAppWhitelistDuration(idleDuration);
@@ -15476,44 +15557,16 @@ public class PackageManagerService extends IPackageManager.Stub
|| mWaitForEnableRollbackToComplete) {
return;
}
-
- if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
- try {
- mInstallObserver.onPackageInstalled(null, mRet, "Dry run", new Bundle());
- } catch (RemoteException e) {
- Slog.i(TAG, "Observer no longer exists.");
- }
- return;
- }
sendVerificationCompleteNotification();
-
- // TODO(samiul): In future return once verification is complete
- processPendingInstall();
- }
-
- private void processPendingInstall() {
- InstallArgs args = createInstallArgs(this);
- if (mRet == PackageManager.INSTALL_SUCCEEDED) {
- mRet = args.copyApk();
- }
- if (mParentInstallParams != null) {
- mParentInstallParams.tryProcessInstallRequest(args, mRet);
- } else {
- PackageInstalledInfo res = createPackageInstalledInfo(mRet);
- processInstallRequestsAsync(
- res.returnCode == PackageManager.INSTALL_SUCCEEDED,
- Collections.singletonList(new InstallRequest(args, res)));
-
- }
}
private void sendVerificationCompleteNotification() {
- if (mParentInstallParams != null) {
- mParentInstallParams.trySendVerificationCompleteNotification(this, mRet);
+ if (mParentVerificationParams != null) {
+ mParentVerificationParams.trySendVerificationCompleteNotification(this, mRet);
} else {
try {
- mVerificationObserver.onPackageInstalled(null, mRet,
- "Package Verification Result", new Bundle());
+ observer.onPackageInstalled(null, mRet, "Package Verification Result",
+ new Bundle());
} catch (RemoteException e) {
Slog.i(TAG, "Observer no longer exists.");
}
@@ -15597,7 +15650,7 @@ public class PackageManagerService extends IPackageManager.Stub
/** New install */
InstallArgs(InstallParams params) {
- this(params.origin, params.move, params.mInstallObserver, params.installFlags,
+ this(params.origin, params.move, params.observer, params.installFlags,
params.installSource, params.volumeUuid,
params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
@@ -16713,7 +16766,7 @@ public class PackageManagerService extends IPackageManager.Stub
reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
- res.removedInfo.broadcastWhitelist = mAppsFilter.getVisibilityWhitelist(
+ res.removedInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(
reconciledPkg.pkgSetting, request.mAllUsers, mSettings.mPackages);
if (reconciledPkg.prepareResult.system) {
// Remove existing system package
@@ -18643,7 +18696,7 @@ public class PackageManagerService extends IPackageManager.Stub
boolean isStaticSharedLib;
// a two dimensional array mapping userId to the set of appIds that can receive notice
// of package changes
- SparseArray<int[]> broadcastWhitelist;
+ SparseArray<int[]> broadcastAllowList;
// Clean up resources deleted packages.
InstallArgs args = null;
@@ -18666,9 +18719,9 @@ public class PackageManagerService extends IPackageManager.Stub
extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
extras.putBoolean(Intent.EXTRA_REPLACING, true);
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, extras,
- 0, null /*targetPackage*/, null, null, null, broadcastWhitelist);
+ 0, null /*targetPackage*/, null, null, null, broadcastAllowList);
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
- extras, 0, null /*targetPackage*/, null, null, null, broadcastWhitelist);
+ extras, 0, null /*targetPackage*/, null, null, null, broadcastAllowList);
packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0,
removedPackage, null, null, null, null /* broadcastWhitelist */);
if (installerPackageName != null) {
@@ -18700,7 +18753,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (removedPackage != null) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
removedPackage, extras, 0, null /*targetPackage*/, null,
- broadcastUsers, instantUserIds, broadcastWhitelist);
+ broadcastUsers, instantUserIds, broadcastAllowList);
if (installerPackageName != null) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
removedPackage, extras, 0 /*flags*/,
@@ -18709,7 +18762,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (dataRemoved && !isRemovedPackageSystemUpdate) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null,
- null, broadcastUsers, instantUserIds, broadcastWhitelist);
+ null, broadcastUsers, instantUserIds, broadcastAllowList);
packageSender.notifyPackageRemoved(removedPackage, removedUid);
}
}
@@ -18722,7 +18775,7 @@ public class PackageManagerService extends IPackageManager.Stub
packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
- null, null, broadcastUsers, instantUserIds, broadcastWhitelist);
+ null, null, broadcastUsers, instantUserIds, broadcastAllowList);
}
}
@@ -19221,6 +19274,13 @@ public class PackageManagerService extends IPackageManager.Stub
final int flags = action.flags;
final boolean systemApp = isSystemApp(ps);
+ // We need to get the permission state before package state is (potentially) destroyed.
+ final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray();
+ for (int userId : allUserHandles) {
+ hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS,
+ packageName, userId) == PERMISSION_GRANTED);
+ }
+
final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
@@ -19287,8 +19347,7 @@ public class PackageManagerService extends IPackageManager.Stub
affectedUserIds = resolveUserIds(userId);
}
for (final int affectedUserId : affectedUserIds) {
- if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS,
- affectedUserId)) {
+ if (hadSuspendAppsPermission.get(affectedUserId)) {
unsuspendForSuspendingPackage(packageName, affectedUserId);
removeAllDistractingPackageRestrictions(affectedUserId);
}
@@ -20755,6 +20814,11 @@ public class PackageManagerService extends IPackageManager.Stub
return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
}
+ public String getOverlayConfigSignaturePackageName() {
+ return ensureSystemPackageName(SystemConfig.getInstance()
+ .getOverlayConfigSignaturePackage());
+ }
+
@Nullable
private String getRetailDemoPackageName() {
final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
@@ -21061,8 +21125,8 @@ public class PackageManagerService extends IPackageManager.Stub
pkgSetting.setEnabled(newState, userId, callingPackage);
if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
|| newState == COMPONENT_ENABLED_STATE_DISABLED)
- && pkgSetting.getPermissionsState().hasPermission(
- Manifest.permission.SUSPEND_APPS, userId)) {
+ && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
+ == PERMISSION_GRANTED) {
// This app should not generally be allowed to get disabled by the UI, but if it
// ever does, we don't want to end up with some of the user's apps permanently
// suspended.
@@ -21214,17 +21278,17 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean isInstantApp = isInstantApp(packageName, userId);
final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
- final SparseArray<int[]> broadcastWhitelist;
+ final SparseArray<int[]> broadcastAllowList;
synchronized (mLock) {
PackageSetting setting = getPackageSettingInternal(packageName, Process.SYSTEM_UID);
if (setting == null) {
return;
}
- broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist(setting,
+ broadcastAllowList = isInstantApp ? null : mAppsFilter.getVisibilityAllowList(setting,
userIds, mSettings.mPackages);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
- userIds, instantUserIds, broadcastWhitelist);
+ userIds, instantUserIds, broadcastAllowList);
}
@Override
@@ -23377,12 +23441,7 @@ public class PackageManagerService extends IPackageManager.Stub
final Message msg = mHandler.obtainMessage(INIT_COPY);
final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
- installSource, volumeUuid, null /*verificationInfo*/, user,
- packageAbiOverride, null /*grantedPermissions*/,
- null /*whitelistedRestrictedPermissions*/, MODE_DEFAULT /* autoRevokePermissions */,
- PackageParser.SigningDetails.UNKNOWN,
- PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST,
- DataLoaderType.NONE);
+ installSource, volumeUuid, user, packageAbiOverride);
params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
@@ -24275,6 +24334,8 @@ public class PackageManagerService extends IPackageManager.Stub
return TextUtils.isEmpty(mRetailDemoPackage)
? ArrayUtils.emptyArray(String.class)
: new String[] {mRetailDemoPackage};
+ case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
+ return filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
default:
return ArrayUtils.emptyArray(String.class);
}
@@ -25628,79 +25689,6 @@ public class PackageManagerService extends IPackageManager.Stub
public List<String> getMimeGroup(String packageName, String mimeGroup) {
return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
}
-
- static class ActiveInstallSession {
- private final String mPackageName;
- private final File mStagedDir;
- private final IPackageInstallObserver2 mInstallObserver;
- // TODO(samiul): We are temporarily assigning two observer to ActiveInstallSession. One for
- // installation and one for verification. This will be fixed within next few CLs.
- private final IPackageInstallObserver2 mVerificationObserver;
- private final int mSessionId;
- private final PackageInstaller.SessionParams mSessionParams;
- private final int mInstallerUid;
- @NonNull private final InstallSource mInstallSource;
- private final UserHandle mUser;
- private final SigningDetails mSigningDetails;
-
- ActiveInstallSession(String packageName, File stagedDir,
- IPackageInstallObserver2 installObserver,
- IPackageInstallObserver2 verificationObserver,
- int sessionId, PackageInstaller.SessionParams sessionParams, int installerUid,
- InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
- mPackageName = packageName;
- mStagedDir = stagedDir;
- mInstallObserver = installObserver;
- mVerificationObserver = verificationObserver;
- mSessionId = sessionId;
- mSessionParams = sessionParams;
- mInstallerUid = installerUid;
- mInstallSource = Preconditions.checkNotNull(installSource);
- mUser = user;
- mSigningDetails = signingDetails;
- }
-
- public String getPackageName() {
- return mPackageName;
- }
-
- public File getStagedDir() {
- return mStagedDir;
- }
-
- public IPackageInstallObserver2 getInstallObserver() {
- return mInstallObserver;
- }
-
- public IPackageInstallObserver2 getVerificationObserver() {
- return mVerificationObserver;
- }
-
- public int getSessionId() {
- return mSessionId;
- }
-
- public PackageInstaller.SessionParams getSessionParams() {
- return mSessionParams;
- }
-
- public int getInstallerUid() {
- return mInstallerUid;
- }
-
- @NonNull
- public InstallSource getInstallSource() {
- return mInstallSource;
- }
-
- public UserHandle getUser() {
- return mUser;
- }
-
- public SigningDetails getSigningDetails() {
- return mSigningDetails;
- }
- }
}
interface PackageSender {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 03f4708c09c4..de0e4b53adab 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -488,6 +488,18 @@ public class PackageManagerServiceUtils {
}
/**
+ * Returns true if the signature set of the package is identical to the specified signature
+ * set or if the signing details of the package are unknown.
+ */
+ public static boolean comparePackageSignatures(PackageSetting pkgSetting,
+ Signature[] signatures) {
+ return pkgSetting.signatures.mSigningDetails
+ == PackageParser.SigningDetails.UNKNOWN
+ || compareSignatures(pkgSetting.signatures.mSigningDetails.signatures, signatures)
+ == PackageManager.SIGNATURE_MATCH;
+ }
+
+ /**
* Used for backward compatibility to make sure any packages with
* certificate chains get upgraded to the new style. {@code existingSigs}
* will be in the old format (since they were stored on disk from before the
diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java
index ea7af9031bd0..cb9c2e997e22 100644
--- a/services/core/java/com/android/server/pm/PackageVerificationState.java
+++ b/services/core/java/com/android/server/pm/PackageVerificationState.java
@@ -19,7 +19,7 @@ package com.android.server.pm;
import android.content.pm.PackageManager;
import android.util.SparseBooleanArray;
-import com.android.server.pm.PackageManagerService.InstallParams;
+import com.android.server.pm.PackageManagerService.VerificationParams;
/**
* Tracks the package verification state for a particular package. Each package verification has a
@@ -28,7 +28,7 @@ import com.android.server.pm.PackageManagerService.InstallParams;
* sufficient verifiers, then package verification is considered complete.
*/
class PackageVerificationState {
- private final InstallParams mParams;
+ private final VerificationParams mParams;
private final SparseBooleanArray mSufficientVerifierUids;
@@ -50,13 +50,13 @@ class PackageVerificationState {
* Create a new package verification state where {@code requiredVerifierUid} is the user ID for
* the package that must reply affirmative before things can continue.
*/
- PackageVerificationState(InstallParams params) {
+ PackageVerificationState(VerificationParams params) {
mParams = params;
mSufficientVerifierUids = new SparseBooleanArray();
mExtendedTimeout = false;
}
- InstallParams getInstallParams() {
+ VerificationParams getVerificationParams() {
return mParams;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 7106499f9b56..1805713387ae 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -435,10 +435,11 @@ public final class Settings {
}
Settings(File dataDir, PermissionSettings permission,
- Object lock) {
+ RuntimePermissionsPersistence runtimePermissionsPersistence, Object lock) {
mLock = lock;
mPermissions = permission;
- mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
+ mRuntimePermissionsPersistence = new RuntimePermissionPersistence(
+ runtimePermissionsPersistence, mLock);
mSystemDir = new File(dataDir, "system");
mSystemDir.mkdirs();
@@ -5381,8 +5382,7 @@ public final class Settings {
private String mExtendedFingerprint;
- private final RuntimePermissionsPersistence mPersistence =
- RuntimePermissionsPersistence.createInstance();
+ private final RuntimePermissionsPersistence mPersistence;
private final Handler mHandler = new MyHandler();
@@ -5407,7 +5407,9 @@ public final class Settings {
// The mapping keys are user ids.
private final SparseBooleanArray mPermissionUpgradeNeeded = new SparseBooleanArray();
- public RuntimePermissionPersistence(Object persistenceLock) {
+ public RuntimePermissionPersistence(RuntimePermissionsPersistence persistence,
+ Object persistenceLock) {
+ mPersistence = persistence;
mPersistenceLock = persistenceLock;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index f16b5b48d913..89ed3c755783 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -108,6 +108,7 @@ import com.android.internal.util.Preconditions;
import com.android.internal.util.StatLogger;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.pm.ShortcutUser.PackageWithUser;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -614,13 +615,13 @@ public class ShortcutService extends IShortcutService.Stub {
}
@Override
- public void onStopUser(int userHandle) {
- mService.handleStopUser(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mService.handleStopUser(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(int userId) {
- mService.handleUnlockUser(userId);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.handleUnlockUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 616e5d13f990..89bdb3ecbff9 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -804,6 +804,7 @@ public class StagingManager {
params.isStaged = false;
if (preReboot) {
params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
+ params.installFlags |= PackageManager.INSTALL_DRY_RUN;
}
final int apkParentSessionId = mPi.createSession(
params, session.getInstallerPackageName(), session.getInstallerAttributionTag(),
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b0d3d53d58b2..8f11fd529e60 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -110,6 +110,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.am.UserState;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -553,9 +554,9 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onStartUser(@UserIdInt int userId) {
+ public void onUserStarting(@NonNull TargetUser targetUser) {
synchronized (mUms.mUsersLock) {
- final UserData user = mUms.getUserDataLU(userId);
+ final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
if (user != null) {
user.startRealtime = SystemClock.elapsedRealtime();
}
@@ -563,9 +564,9 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onUnlockUser(@UserIdInt int userId) {
+ public void onUserUnlocking(@NonNull TargetUser targetUser) {
synchronized (mUms.mUsersLock) {
- final UserData user = mUms.getUserDataLU(userId);
+ final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
if (user != null) {
user.unlockRealtime = SystemClock.elapsedRealtime();
}
@@ -573,9 +574,9 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public void onStopUser(@UserIdInt int userId) {
+ public void onUserStopping(@NonNull TargetUser targetUser) {
synchronized (mUms.mUsersLock) {
- final UserData user = mUms.getUserDataLU(userId);
+ final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
if (user != null) {
user.startRealtime = 0;
user.unlockRealtime = 0;
diff --git a/services/core/java/com/android/server/pm/dex/OWNERS b/services/core/java/com/android/server/pm/dex/OWNERS
index fcc1f6c10eac..5a4431ee8c89 100644
--- a/services/core/java/com/android/server/pm/dex/OWNERS
+++ b/services/core/java/com/android/server/pm/dex/OWNERS
@@ -1,4 +1,2 @@
-agampe@google.com
calin@google.com
ngeoffray@google.com
-sehr@google.com
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 5c5942da4546..be93b8f95b79 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1928,10 +1928,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
if (doGrant && packageName != null) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
- userId);
- }
+ mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
+ userId);
}
return true;
}
@@ -1941,10 +1939,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int callingUid = Binder.getCallingUid();
PackageManagerServiceUtils
.enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
- synchronized (mLock) {
- Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
- }
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
}
@Override
@@ -1952,10 +1948,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int callingUid = Binder.getCallingUid();
PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
"grantDefaultPermissionsToEnabledImsServices", callingUid);
- synchronized (mLock) {
- Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
- }
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
}
@Override
@@ -1964,11 +1958,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int callingUid = Binder.getCallingUid();
PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
"grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
- synchronized (mLock) {
- Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToEnabledTelephonyDataServices(
- packageNames, userId));
- }
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToEnabledTelephonyDataServices(packageNames, userId));
}
@Override
@@ -1977,11 +1968,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int callingUid = Binder.getCallingUid();
PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
"revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
- synchronized (mLock) {
- Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
- .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
- packageNames, userId));
- }
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .revokeDefaultPermissionsFromDisabledTelephonyDataServices(packageNames, userId));
}
@Override
@@ -1989,10 +1977,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int callingUid = Binder.getCallingUid();
PackageManagerServiceUtils
.enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
- synchronized (mLock) {
- Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
- }
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
}
@Override
@@ -2000,10 +1986,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int callingUid = Binder.getCallingUid();
PackageManagerServiceUtils
.enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
- synchronized (mLock) {
- Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
- .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
- }
+ Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+ .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
}
@Override
@@ -4889,58 +4873,42 @@ public class PermissionManagerService extends IPermissionManager.Stub {
@Override
public void setDialerAppPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
}
@Override
public void setLocationExtraPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
}
@Override
public void setLocationPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
}
@Override
public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
}
@Override
public void setSmsAppPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
}
@Override
public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
}
@Override
public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
}
@Override
public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
- }
+ mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
}
@Override
@@ -4972,26 +4940,20 @@ public class PermissionManagerService extends IPermissionManager.Stub {
@Override
public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
- }
+ mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
+ packageName, userId);
}
@Override
public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
- }
+ mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
+ packageName, userId);
}
@Override
public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
- synchronized (mLock) {
- mDefaultPermissionGrantPolicy
- .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
- }
+ mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
+ userId);
}
@Override
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 37f088b170eb..4d48a2e63b30 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -67,6 +67,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;
@@ -347,7 +348,11 @@ public final class PermissionPolicyService extends SystemService {
}
@Override
- public void onStartUser(@UserIdInt int userId) {
+ public void onUserStarting(@NonNull TargetUser user) {
+ onStartUser(user.getUserIdentifier());
+ }
+
+ private void onStartUser(@UserIdInt int userId) {
if (DEBUG) Slog.i(LOG_TAG, "onStartUser(" + userId + ")");
if (isStarted(userId)) {
@@ -373,11 +378,11 @@ public final class PermissionPolicyService extends SystemService {
}
@Override
- public void onStopUser(@UserIdInt int userId) {
- if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + userId + ")");
+ public void onUserStopping(@NonNull TargetUser user) {
+ if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + user + ")");
synchronized (mLock) {
- mIsStarted.delete(userId);
+ mIsStarted.delete(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a2b46a08dc42..f9a49c9d8244 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -493,9 +493,6 @@ public final class PowerManagerService extends SystemService
private boolean mProximityPositive;
// Screen brightness setting limits.
- private float mScreenBrightnessSettingMinimum;
- private float mScreenBrightnessSettingMaximum;
- private float mScreenBrightnessSettingDefault;
public final float mScreenBrightnessMinimum;
public final float mScreenBrightnessMaximum;
public final float mScreenBrightnessDefault;
@@ -1030,14 +1027,6 @@ public final class PowerManagerService extends SystemService
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
mAttentionDetector.systemReady(mContext);
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mScreenBrightnessSettingMinimum = pm.getBrightnessConstraint(
- PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
- mScreenBrightnessSettingMaximum = pm.getBrightnessConstraint(
- PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
- mScreenBrightnessSettingDefault = pm.getBrightnessConstraint(
- PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT);
-
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
// The notifier runs on the system server's main looper so as not to interfere
@@ -2818,7 +2807,7 @@ public final class PowerManagerService extends SystemService
// Keep the brightness steady during boot. This requires the
// bootloader brightness and the default brightness to be identical.
autoBrightness = false;
- screenBrightnessOverride = mScreenBrightnessSettingDefault;
+ screenBrightnessOverride = mScreenBrightnessDefault;
} else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
autoBrightness = false;
screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
@@ -3869,9 +3858,9 @@ public final class PowerManagerService extends SystemService
pw.println(" mDrawWakeLockOverrideFromSidekick=" + mDrawWakeLockOverrideFromSidekick);
pw.println(" mDozeScreenBrightnessOverrideFromDreamManager="
+ mDozeScreenBrightnessOverrideFromDreamManager);
- pw.println(" mScreenBrightnessSettingMinimumFloat=" + mScreenBrightnessSettingMinimum);
- pw.println(" mScreenBrightnessSettingMaximumFloat=" + mScreenBrightnessSettingMaximum);
- pw.println(" mScreenBrightnessSettingDefaultFloat=" + mScreenBrightnessSettingDefault);
+ pw.println(" mScreenBrightnessMinimum=" + mScreenBrightnessMinimum);
+ pw.println(" mScreenBrightnessMaximum=" + mScreenBrightnessMaximum);
+ pw.println(" mScreenBrightnessDefault=" + mScreenBrightnessDefault);
pw.println(" mDoubleTapWakeEnabled=" + mDoubleTapWakeEnabled);
pw.println(" mIsVrModeEnabled=" + mIsVrModeEnabled);
pw.println(" mForegroundProfile=" + mForegroundProfile);
@@ -4228,15 +4217,15 @@ public final class PowerManagerService extends SystemService
proto.write(
PowerServiceSettingsAndConfigurationDumpProto.ScreenBrightnessSettingLimitsProto
.SETTING_MINIMUM_FLOAT,
- mScreenBrightnessSettingMinimum);
+ mScreenBrightnessMinimum);
proto.write(
PowerServiceSettingsAndConfigurationDumpProto.ScreenBrightnessSettingLimitsProto
.SETTING_MAXIMUM_FLOAT,
- mScreenBrightnessSettingMaximum);
+ mScreenBrightnessMaximum);
proto.write(
PowerServiceSettingsAndConfigurationDumpProto.ScreenBrightnessSettingLimitsProto
.SETTING_DEFAULT_FLOAT,
- mScreenBrightnessSettingDefault);
+ mScreenBrightnessDefault);
proto.end(screenBrightnessSettingLimitsToken);
proto.write(
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 392792dbae69..a291cef5b39e 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -34,14 +34,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.PermissionChecker;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
-import android.database.CursorWindow;
import android.os.Binder;
-import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
@@ -74,6 +71,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import java.io.ByteArrayOutputStream;
@@ -217,8 +215,8 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
}
@Override
- public void onStartUser(@UserIdInt int userId) {
- maybeGrantDefaultRolesSync(userId);
+ public void onUserStarting(@NonNull TargetUser user) {
+ maybeGrantDefaultRolesSync(user.getUserIdentifier());
}
@MainThread
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerService.java b/services/core/java/com/android/server/rollback/RollbackManagerService.java
index ce1156bbe059..04a5ca515c5c 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerService.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerService.java
@@ -16,10 +16,12 @@
package com.android.server.rollback;
+import android.annotation.NonNull;
import android.content.Context;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
/**
* Service that manages APK level rollbacks. Publishes
@@ -43,8 +45,8 @@ public final class RollbackManagerService extends SystemService {
}
@Override
- public void onUserUnlocking(TargetUser user) {
- mService.onUnlockUser(user.getUserHandle().getIdentifier());
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.onUnlockUser(user.getUserIdentifier());
}
@Override
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index fea68d3090f0..7091c47b8e83 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -16,9 +16,7 @@
package com.android.server.search;
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
+import android.annotation.NonNull;
import android.app.ISearchManager;
import android.app.SearchManager;
import android.app.SearchableInfo;
@@ -26,18 +24,14 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
import android.database.ContentObserver;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.service.voice.VoiceInteractionService;
import android.util.Log;
import android.util.SparseArray;
@@ -48,6 +42,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.FileDescriptor;
@@ -76,18 +71,13 @@ public class SearchManagerService extends ISearchManager.Stub {
}
@Override
- public void onUnlockUser(final int userId) {
- mService.mHandler.post(new Runnable() {
- @Override
- public void run() {
- mService.onUnlockUser(userId);
- }
- });
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.mHandler.post(() -> mService.onUnlockUser(user.getUserIdentifier()));
}
@Override
- public void onCleanupUser(int userHandle) {
- mService.onCleanupUser(userHandle);
+ public void onUserStopped(@NonNull TargetUser user) {
+ mService.onCleanupUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 7c8c49461e64..4349ca451c36 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -26,6 +26,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.SYSTEM_UID;
import android.Manifest.permission;
+import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.app.slice.ISliceManager;
import android.app.slice.SliceSpec;
@@ -59,10 +60,10 @@ import android.util.Xml.Encoding;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
-import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -615,13 +616,13 @@ public class SliceManagerService extends ISliceManager.Stub {
}
@Override
- public void onUnlockUser(int userHandle) {
- mService.onUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.onUnlockUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- mService.onStopUser(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mService.onStopUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
index 361a5067b9bf..1c29c69239f6 100644
--- a/services/core/java/com/android/server/storage/StorageUserConnection.java
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -29,6 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
@@ -64,9 +65,6 @@ public final class StorageUserConnection {
private static final String TAG = "StorageUserConnection";
private static final int DEFAULT_REMOTE_TIMEOUT_SECONDS = 20;
- // TODO(b/161702661): Workaround for demo user to have shorter timeout.
- // This allows the DevicePolicyManagerService#enableSystemApp call to succeed without ANR.
- private static final int DEMO_USER_REMOTE_TIMEOUT_SECONDS = 5;
private final Object mLock = new Object();
private final Context mContext;
@@ -75,6 +73,7 @@ public final class StorageUserConnection {
private final ActiveConnection mActiveConnection = new ActiveConnection();
private final boolean mIsDemoUser;
@GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>();
+ @GuardedBy("mLock") @Nullable private HandlerThread mHandlerThread;
public StorageUserConnection(Context context, int userId, StorageSessionController controller) {
mContext = Objects.requireNonNull(context);
@@ -82,6 +81,10 @@ public final class StorageUserConnection {
mSessionController = controller;
mIsDemoUser = LocalServices.getService(UserManagerInternal.class)
.getUserInfo(userId).isDemo();
+ if (mIsDemoUser) {
+ mHandlerThread = new HandlerThread("StorageUserConnectionThread-" + mUserId);
+ mHandlerThread.start();
+ }
}
/**
@@ -188,6 +191,9 @@ public final class StorageUserConnection {
*/
public void close() {
mActiveConnection.close();
+ if (mIsDemoUser) {
+ mHandlerThread.quit();
+ }
}
/** Returns all created sessions. */
@@ -207,8 +213,7 @@ public final class StorageUserConnection {
private void waitForLatch(CountDownLatch latch, String reason) throws TimeoutException {
try {
- if (!latch.await(mIsDemoUser ? DEMO_USER_REMOTE_TIMEOUT_SECONDS
- : DEFAULT_REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
+ if (!latch.await(DEFAULT_REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
// TODO(b/140025078): Call ActivityManager ANR API?
Slog.wtf(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId);
throw new TimeoutException("Latch wait for " + reason + " elapsed");
@@ -424,15 +429,32 @@ public final class StorageUserConnection {
};
Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId);
- if (mContext.bindServiceAsUser(new Intent().setComponent(name), mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
- UserHandle.of(mUserId))) {
- Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
- return mLatch;
+ if (mIsDemoUser) {
+ // Schedule on a worker thread for demo user to avoid deadlock
+ if (mContext.bindServiceAsUser(new Intent().setComponent(name),
+ mServiceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ mHandlerThread.getThreadHandler(),
+ UserHandle.of(mUserId))) {
+ Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
+ return mLatch;
+ } else {
+ mIsConnecting = false;
+ throw new ExternalStorageServiceException(
+ "Failed to bind to the ExternalStorageService for user " + mUserId);
+ }
} else {
- mIsConnecting = false;
- throw new ExternalStorageServiceException(
- "Failed to bind to the ExternalStorageService for user " + mUserId);
+ if (mContext.bindServiceAsUser(new Intent().setComponent(name),
+ mServiceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.of(mUserId))) {
+ Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
+ return mLatch;
+ } else {
+ mIsConnecting = false;
+ throw new ExternalStorageServiceException(
+ "Failed to bind to the ExternalStorageService for user " + mUserId);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 1707d9542813..363e86dea8b1 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -66,6 +66,7 @@ import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -118,14 +119,14 @@ public final class TextClassificationManagerService extends ITextClassifierServi
}
@Override
- public void onStartUser(int userId) {
- processAnyPendingWork(userId);
+ public void onUserStarting(@NonNull TargetUser user) {
+ processAnyPendingWork(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(int userId) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
// Rebind if we failed earlier due to locked encrypted user
- processAnyPendingWork(userId);
+ processAnyPendingWork(user.getUserIdentifier());
}
private void processAnyPendingWork(int userId) {
@@ -135,7 +136,9 @@ public final class TextClassificationManagerService extends ITextClassifierServi
}
@Override
- public void onStopUser(int userId) {
+ public void onUserStopping(@NonNull TargetUser user) {
+ int userId = user.getUserIdentifier();
+
synchronized (mManagerService.mLock) {
UserState userState = mManagerService.peekUserStateLocked(userId);
if (userState != null) {
diff --git a/services/core/java/com/android/server/textservices/TextServicesManagerService.java b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
index e0bac93cce16..f39067b110a8 100644
--- a/services/core/java/com/android/server/textservices/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
@@ -58,6 +58,7 @@ import com.android.internal.textservice.ITextServicesSessionListener;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import org.xmlpull.v1.XmlPullParserException;
@@ -287,21 +288,21 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
@Override
- public void onStopUser(@UserIdInt int userHandle) {
+ public void onUserStopping(@NonNull TargetUser user) {
if (DBG) {
- Slog.d(TAG, "onStopUser userId: " + userHandle);
+ Slog.d(TAG, "onStopUser user: " + user);
}
- mService.onStopUser(userHandle);
+ mService.onStopUser(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(@UserIdInt int userHandle) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
if(DBG) {
- Slog.d(TAG, "onUnlockUser userId: " + userHandle);
+ Slog.d(TAG, "onUnlockUser userId: " + user);
}
// Called on the system server's main looper thread.
// TODO: Dispatch this to a worker thread as needed.
- mService.onUnlockUser(userHandle);
+ mService.onUnlockUser(user.getUserIdentifier());
}
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index fd3c1f97df8b..6adff0d32d88 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -17,6 +17,8 @@
package com.android.server.trust;
import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlarmManager;
@@ -71,6 +73,7 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -1042,28 +1045,28 @@ public class TrustManagerService extends SystemService {
// User lifecycle
@Override
- public void onStartUser(int userId) {
- mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
+ public void onUserStarting(@NonNull TargetUser user) {
+ mHandler.obtainMessage(MSG_START_USER, user.getUserIdentifier(), 0, null).sendToTarget();
}
@Override
- public void onCleanupUser(int userId) {
- mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
+ public void onUserStopped(@NonNull TargetUser user) {
+ mHandler.obtainMessage(MSG_CLEANUP_USER, user.getUserIdentifier(), 0, null).sendToTarget();
}
@Override
- public void onSwitchUser(int userId) {
- mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mHandler.obtainMessage(MSG_SWITCH_USER, to.getUserIdentifier(), 0, null).sendToTarget();
}
@Override
- public void onUnlockUser(int userId) {
- mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mHandler.obtainMessage(MSG_UNLOCK_USER, user.getUserIdentifier(), 0, null).sendToTarget();
}
@Override
- public void onStopUser(@UserIdInt int userId) {
- mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
+ public void onUserStopping(@NonNull TargetUser user) {
+ mHandler.obtainMessage(MSG_STOP_USER, user.getUserIdentifier(), 0, null).sendToTarget();
}
// Plumbing
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 323ac7b8806e..b3ec849e6c90 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -20,6 +20,7 @@ import static android.media.AudioManager.DEVICE_NONE;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
@@ -83,6 +84,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import java.io.File;
import java.io.FileDescriptor;
@@ -165,10 +167,10 @@ public final class TvInputManagerService extends SystemService {
}
@Override
- public void onUnlockUser(int userHandle) {
- if (DEBUG) Slog.d(TAG, "onUnlockUser(userHandle=" + userHandle + ")");
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ if (DEBUG) Slog.d(TAG, "onUnlockUser(user=" + user + ")");
synchronized (mLock) {
- if (mCurrentUserId != userHandle) {
+ if (mCurrentUserId != user.getUserIdentifier()) {
return;
}
buildTvInputListLocked(mCurrentUserId, null);
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 45689ce73c9f..ae873e2fe467 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -19,6 +19,7 @@ import static android.view.Display.INVALID_DISPLAY;
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
@@ -65,6 +66,7 @@ import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.utils.ManagedApplicationService;
import com.android.server.utils.ManagedApplicationService.BinderChecker;
import com.android.server.utils.ManagedApplicationService.LogEvent;
@@ -817,14 +819,14 @@ public class VrManagerService extends SystemService
}
@Override
- public void onStartUser(int userHandle) {
+ public void onUserStarting(@NonNull TargetUser user) {
synchronized (mLock) {
mComponentObserver.onUsersChanged();
}
}
@Override
- public void onSwitchUser(int userHandle) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
FgThread.getHandler().post(() -> {
synchronized (mLock) {
mComponentObserver.onUsersChanged();
@@ -834,7 +836,7 @@ public class VrManagerService extends SystemService
}
@Override
- public void onStopUser(int userHandle) {
+ public void onUserStopping(@NonNull TargetUser user) {
synchronized (mLock) {
mComponentObserver.onUsersChanged();
}
@@ -842,7 +844,7 @@ public class VrManagerService extends SystemService
}
@Override
- public void onCleanupUser(int userHandle) {
+ public void onUserStopped(@NonNull TargetUser user) {
synchronized (mLock) {
mComponentObserver.onUsersChanged();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 90f87b16e70d..2f695c6fd3f1 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -105,6 +105,7 @@ import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.wm.WindowManagerInternal;
@@ -166,9 +167,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
@Override
- public void onUnlockUser(int userHandle) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
if (mService != null) {
- mService.onUnlockUser(userHandle);
+ mService.onUnlockUser(user.getUserIdentifier());
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index dd67b3d2c330..b72ff2db7e6c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2865,7 +2865,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (hasProcess()) {
if (removeFromApp) {
- app.removeActivity(this);
+ app.removeActivity(this, true /* keepAssociation */);
if (!app.hasActivities()) {
mAtmService.clearHeavyWeightProcessIfEquals(app);
// Update any services we are bound to that might care about whether
@@ -2914,7 +2914,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
setState(DESTROYED,
"destroyActivityLocked. not finishing or skipping destroy");
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + this);
- app = null;
+ detachFromProcess();
}
} else {
// Remove this record from the history.
@@ -2963,13 +2963,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
setState(DESTROYED, "removeFromHistory");
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this);
- app = null;
+ detachFromProcess();
removeAppTokenFromDisplay();
cleanUpActivityServices();
removeUriPermissionsLocked();
}
+ void detachFromProcess() {
+ if (app != null) {
+ app.removeActivity(this, false /* keepAssociation */);
+ }
+ app = null;
+ }
+
void makeFinishingLocked() {
if (finishing) {
return;
@@ -3019,7 +3026,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (setState) {
setState(DESTROYED, "cleanUp");
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + this);
- app = null;
+ detachFromProcess();
}
// Inform supervisor the activity has been removed.
@@ -3160,6 +3167,64 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mServiceConnectionsHolder = null;
}
+ /**
+ * Detach this activity from process and clear the references to it. If the activity is
+ * finishing or has no saved state or crashed many times, it will also be removed from history.
+ */
+ void handleAppDied() {
+ final boolean remove;
+ if ((mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
+ || mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
+ && launchCount < 3 && !finishing) {
+ // If the process crashed during a resize, always try to relaunch it, unless it has
+ // failed more than twice. Skip activities that's already finishing cleanly by itself.
+ remove = false;
+ } else if ((!mHaveState && !stateNotNeeded
+ && !isState(ActivityState.RESTARTING_PROCESS)) || finishing) {
+ // Don't currently have state for the activity, or it is finishing -- always remove it.
+ remove = true;
+ } else if (!mVisibleRequested && launchCount > 2
+ && lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
+ // We have launched this activity too many times since it was able to run, so give up
+ // and remove it. (Note if the activity is visible, we don't remove the record. We leave
+ // the dead window on the screen but the process will not be restarted unless user
+ // explicitly tap on it.)
+ remove = true;
+ } else {
+ // The process may be gone, but the activity lives on!
+ remove = false;
+ }
+ if (remove) {
+ if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
+ Slog.i(TAG_ADD_REMOVE, "Removing activity " + this
+ + " hasSavedState=" + mHaveState + " stateNotNeeded=" + stateNotNeeded
+ + " finishing=" + finishing + " state=" + mState
+ + " callers=" + Debug.getCallers(5));
+ }
+ if (!finishing || (app != null && app.isRemoved())) {
+ Slog.w(TAG, "Force removing " + this + ": app died, no saved state");
+ EventLogTags.writeWmFinishActivity(mUserId, System.identityHashCode(this),
+ task != null ? task.mTaskId : -1, shortComponentName,
+ "proc died without state saved");
+ }
+ } else {
+ // We have the current state for this activity, so it can be restarted later
+ // when needed.
+ if (DEBUG_APP) {
+ Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this);
+ }
+ // Set nowVisible to previous visible state. If the app was visible while it died, we
+ // leave the dead window on screen so it's basically visible. This is needed when user
+ // later tap on the dead window, we need to stop other apps when user transfers focus
+ // to the restarted activity.
+ nowVisible = mVisibleRequested;
+ }
+ cleanUp(true /* cleanServices */, true /* setState */);
+ if (remove) {
+ removeFromHistory("appDied");
+ }
+ }
+
@Override
void removeImmediately() {
onRemovedFromDisplay();
@@ -4114,6 +4179,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Now that the app is going invisible, we can remove it. It will be restarted
// if made visible again.
removeDeadWindows();
+ // If this activity is about to finish/stopped and now becomes invisible, remove it
+ // from the unknownApp list in case the activity does not want to draw anything, which
+ // keep the user waiting for the next transition to start.
+ if (finishing || isState(STOPPED)) {
+ displayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
+ }
} else {
if (!appTransition.isTransitionSet()
&& appTransition.isReady()) {
@@ -5919,10 +5990,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// stack, i.e. the hierarchy of the surfaces is unchanged.
if (inPinnedWindowingMode()) {
return getStack().getSurfaceControl();
- } else if (WindowManagerService.sHierarchicalAnimations) {
- return super.getAnimationLeashParent();
} else {
- return getAppAnimationLayer();
+ return super.getAnimationLeashParent();
}
}
@@ -6010,11 +6079,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mAnimationBoundsLayer = createAnimationBoundsLayer(t);
// Crop to stack bounds.
- if (!WindowManagerService.sHierarchicalAnimations) {
- // For Hierarchical animation, we don't need to set window crop since the leash
- // surface size has already same as the animating container.
- t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
- }
t.setLayer(leash, 0);
t.setLayer(mAnimationBoundsLayer, getAnimationLayer());
@@ -7568,6 +7632,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
@Override
+ boolean canCustomizeAppTransition() {
+ return true;
+ }
+
+ @Override
public String toString() {
if (stringName != null) {
return stringName + " t" + (task == null ? INVALID_TASK_ID : task.mTaskId) +
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 04b1edc3eede..ed1ea353eb3e 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -891,7 +891,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// This is the first time we failed -- restart process and
// retry.
r.launchFailed = true;
- proc.removeActivity(r);
+ proc.removeActivity(r, true /* keepAssociation */);
throw e;
}
} finally {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c4af3e2c04c9..5534b8c257f0 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -254,6 +254,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.SystemServiceManager;
import com.android.server.UiThread;
import com.android.server.Watchdog;
@@ -1027,16 +1028,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
- public void onUnlockUser(int userId) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
- mService.mStackSupervisor.onUserUnlocked(userId);
+ mService.mStackSupervisor.onUserUnlocked(user.getUserIdentifier());
}
}
@Override
- public void onCleanupUser(int userId) {
+ public void onUserStopped(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
- mService.mStackSupervisor.mLaunchParamsPersister.onCleanupUser(userId);
+ mService.mStackSupervisor.mLaunchParamsPersister
+ .onCleanupUser(user.getUserIdentifier());
}
}
@@ -6789,11 +6791,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public void handleAppDied(WindowProcessController wpc, boolean restarting,
Runnable finishInstrumentationCallback) {
synchronized (mGlobalLockWithoutBoost) {
- // Remove this application's activities from active lists.
- boolean hasVisibleActivities = mRootWindowContainer.handleAppDied(wpc);
-
- wpc.clearRecentTasks();
- wpc.clearActivities();
+ mStackSupervisor.beginDeferResume();
+ final boolean hasVisibleActivities;
+ try {
+ // Remove this application's activities from active lists.
+ hasVisibleActivities = wpc.handleAppDied();
+ } finally {
+ mStackSupervisor.endDeferResume();
+ }
if (wpc.isInstrumenting()) {
finishInstrumentationCallback.run();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 3abc54f8f2eb..11a468be8f9f 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -203,6 +203,7 @@ public class AppTransition implements Dump {
private static final int NEXT_TRANSIT_TYPE_REMOTE = 10;
private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
+ private boolean mNextAppTransitionOverrideRequested;
// These are the possible states for the enter/exit activities during a thumbnail transition
private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
@@ -337,6 +338,11 @@ public class AppTransition implements Dump {
mNextAppTransitionFlags |= flags;
setLastAppTransition(TRANSIT_UNSET, null, null, null);
updateBooster();
+ if (isTransitionSet()) {
+ removeAppTransitionTimeoutCallbacks();
+ mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable,
+ APP_TRANSITION_TIMEOUT_MS);
+ }
}
void setLastAppTransition(int transit, ActivityRecord openingApp, ActivityRecord closingApp,
@@ -454,6 +460,7 @@ public class AppTransition implements Dump {
void clear() {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
+ mNextAppTransitionOverrideRequested = false;
mNextAppTransitionPackage = null;
mNextAppTransitionAnimationsSpecs.clear();
mRemoteAnimationController = null;
@@ -1574,6 +1581,7 @@ public class AppTransition implements Dump {
*/
boolean canSkipFirstFrame() {
return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
+ && !mNextAppTransitionOverrideRequested
&& mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
&& mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL
&& mNextAppTransition != TRANSIT_KEYGUARD_GOING_AWAY;
@@ -1608,6 +1616,11 @@ public class AppTransition implements Dump {
int orientation, Rect frame, Rect displayFrame, Rect insets,
@Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
boolean freeform, WindowContainer container) {
+
+ if (mNextAppTransitionOverrideRequested && container.canCustomizeAppTransition()) {
+ mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
+ }
+
Animation a;
if (isKeyguardGoingAwayTransit(transit) && enter) {
a = loadKeyguardExitAnimation(transit);
@@ -1648,7 +1661,6 @@ public class AppTransition implements Dump {
"applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
+ "isEntrance=%b Callers=%s",
a, appTransitionToString(transit), enter, Debug.getCallers(3));
- setAppTransitionFinishedCallbackIfNeeded(a);
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
@@ -1775,6 +1787,7 @@ public class AppTransition implements Dump {
a, animAttr, appTransitionToString(transit), enter,
Debug.getCallers(3));
}
+ setAppTransitionFinishedCallbackIfNeeded(a);
return a;
}
@@ -1816,7 +1829,7 @@ public class AppTransition implements Dump {
IRemoteCallback startedCallback, IRemoteCallback endedCallback) {
if (canOverridePendingAppTransition()) {
clear();
- mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
+ mNextAppTransitionOverrideRequested = true;
mNextAppTransitionPackage = packageName;
mNextAppTransitionEnter = enterAnim;
mNextAppTransitionExit = exitAnim;
@@ -2134,15 +2147,16 @@ public class AppTransition implements Dump {
pw.print(prefix); pw.print("mNextAppTransitionType=");
pw.println(transitTypeToString());
}
+ if (mNextAppTransitionOverrideRequested
+ || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
+ pw.print(prefix); pw.print("mNextAppTransitionPackage=");
+ pw.println(mNextAppTransitionPackage);
+ pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
+ pw.print(Integer.toHexString(mNextAppTransitionEnter));
+ pw.print(" mNextAppTransitionExit=0x");
+ pw.println(Integer.toHexString(mNextAppTransitionExit));
+ }
switch (mNextAppTransitionType) {
- case NEXT_TRANSIT_TYPE_CUSTOM:
- pw.print(prefix); pw.print("mNextAppTransitionPackage=");
- pw.println(mNextAppTransitionPackage);
- pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
- pw.print(Integer.toHexString(mNextAppTransitionEnter));
- pw.print(" mNextAppTransitionExit=0x");
- pw.println(Integer.toHexString(mNextAppTransitionExit));
- break;
case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
pw.print(prefix); pw.print("mNextAppTransitionPackage=");
pw.println(mNextAppTransitionPackage);
@@ -2229,12 +2243,7 @@ public class AppTransition implements Dump {
setAppTransition(transit, flags);
}
}
- boolean prepared = prepare();
- if (isTransitionSet()) {
- removeAppTransitionTimeoutCallbacks();
- mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable, APP_TRANSITION_TIMEOUT_MS);
- }
- return prepared;
+ return prepare();
}
/**
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index d60d098071cc..5720e9b7f193 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -411,10 +411,6 @@ public class AppTransitionController {
}
}
- if (!WindowManagerService.sHierarchicalAnimations) {
- return new ArraySet<>(candidates);
- }
-
final ArraySet<ActivityRecord> otherApps = visible ? closingApps : openingApps;
// Ancestors of closing apps while finding animation targets for opening apps, or ancestors
// of opening apps while finding animation targets for closing apps.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 77fc2283d443..fc170538994c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5405,6 +5405,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
private ActivityRecord mAnimatingRecents;
+ /** Whether {@link #mAnimatingRecents} is going to be the top activity. */
+ private boolean mRecentsWillBeTop;
+
/**
* If the recents activity has a fixed orientation which is different from the current top
* activity, it will be rotated before being shown so we avoid a screen rotation animation
@@ -5430,10 +5433,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* If {@link #mAnimatingRecents} still has fixed rotation, it should be moved to top so we
* don't clear {@link #mFixedRotationLaunchingApp} that will be handled by transition.
*/
- void onFinishRecentsAnimation(boolean moveRecentsToBack) {
+ void onFinishRecentsAnimation() {
final ActivityRecord animatingRecents = mAnimatingRecents;
+ final boolean recentsWillBeTop = mRecentsWillBeTop;
mAnimatingRecents = null;
- if (!moveRecentsToBack) {
+ mRecentsWillBeTop = false;
+ if (recentsWillBeTop) {
// The recents activity will be the top, such as staying at recents list or
// returning to home (if home and recents are the same activity).
return;
@@ -5456,6 +5461,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
}
+ void notifyRecentsWillBeTop() {
+ mRecentsWillBeTop = true;
+ }
+
/**
* Return {@code true} if there is an ongoing animation to the "Recents" activity and this
* activity as a fixed orientation so shouldn't be rotated.
@@ -5476,6 +5485,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (r == null || r == mAnimatingRecents) {
return;
}
+ if (mAnimatingRecents != null && mRecentsWillBeTop) {
+ // The activity is not the recents and it should be moved to back later, so it is
+ // better to keep its current appearance for the next transition. Otherwise the
+ // display orientation may be updated too early and the layout procedures at the
+ // end of finishing recents animation is skipped. That causes flickering because
+ // the surface of closing app hasn't updated to invisible.
+ return;
+ }
if (mFixedRotationLaunchingApp == null) {
// In most cases this is a no-op if the activity doesn't have fixed rotation.
// Otherwise it could be from finishing recents animation while the display has
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index f5bd4cd866a6..6b3a5d6bf18c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -702,6 +702,11 @@ public class RecentsAnimationController implements DeathRecipient {
"cleanupAnimation(): Notify animation finished mPendingAnimations=%d "
+ "reorderMode=%d",
mPendingAnimations.size(), reorderMode);
+ if (reorderMode != REORDER_MOVE_TO_ORIGINAL_POSITION) {
+ // Notify the state at the beginning because the removeAnimation may notify the
+ // transition is finished. This is a signal that there will be a next transition.
+ mDisplayContent.mFixedRotationTransitionListener.notifyRecentsWillBeTop();
+ }
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
@@ -742,8 +747,7 @@ public class RecentsAnimationController implements DeathRecipient {
mTargetActivityRecord.token);
}
}
- mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(
- reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION /* moveRecentsToBack */);
+ mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
// Notify that the animation has ended
if (mStatusBar != null) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 06dec7c8023d..ac96d144c4d0 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2155,6 +2155,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore
// to its previous freeform bounds.
stack.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds);
+ stack.setBounds(task.getBounds());
// There are multiple activities in the task and moving the top activity should
// reveal/leave the other activities in their original task.
@@ -2751,7 +2752,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
if (r.app != app) return;
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
- r.app = null;
+ r.detachFromProcess();
r.getDisplay().mDisplayContent.prepareAppTransition(
TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
r.destroyIfPossible("handleAppCrashed");
@@ -3104,22 +3105,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return null;
}
- boolean handleAppDied(WindowProcessController app) {
- if (app.isRemoved()) {
- // The package of the died process should be force-stopped, so make its activities as
- // finishing to prevent the process from being started again if the next top (or being
- // visible) activity also resides in the same process.
- app.makeFinishingForProcessRemoved();
- }
- return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
- result |= stack.handleAppDied(app);
- }
- return result;
- }, false /* initValue */);
- }
-
void closeSystemDialogActivities(String reason) {
forAllActivities((r) -> {
if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 35bd78c6bd06..f3620050bed2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -86,8 +86,6 @@ import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
@@ -115,8 +113,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIB
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.H.FIRST_ACTIVITY_STACK_MSG;
-import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
-import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
import static com.android.server.wm.IdentifierProto.HASH_CODE;
import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
@@ -746,111 +742,6 @@ class Task extends WindowContainer<WindowContainer> {
}
}
- // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this?
- private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp =
- new RemoveHistoryRecordsForApp();
- private class RemoveHistoryRecordsForApp {
- private boolean mHasVisibleActivities;
- private boolean mIsProcessRemoved;
- private WindowProcessController mApp;
- private ArrayList<ActivityRecord> mToRemove = new ArrayList<>();
-
- boolean process(WindowProcessController app) {
- mToRemove.clear();
- mHasVisibleActivities = false;
- mApp = app;
- mIsProcessRemoved = app.isRemoved();
-
- final PooledConsumer c = PooledLambda.obtainConsumer(
- RemoveHistoryRecordsForApp::addActivityToRemove, this,
- PooledLambda.__(ActivityRecord.class));
- forAllActivities(c);
- c.recycle();
-
- while (!mToRemove.isEmpty()) {
- processActivity(mToRemove.remove(0));
- }
-
- mApp = null;
- return mHasVisibleActivities;
- }
-
- private void addActivityToRemove(ActivityRecord r) {
- if (r.app == mApp) {
- mToRemove.add(r);
- }
- }
-
- private void processActivity(ActivityRecord r) {
- if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app);
-
- if (r.app != mApp) {
- return;
- }
- if (r.isVisible() || r.mVisibleRequested) {
- // While an activity launches a new activity, it's possible that the old
- // activity is already requested to be hidden (mVisibleRequested=false), but
- // this visibility is not yet committed, so isVisible()=true.
- mHasVisibleActivities = true;
- }
- final boolean remove;
- if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
- || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
- && r.launchCount < 3 && !r.finishing) {
- // If the process crashed during a resize, always try to relaunch it, unless
- // it has failed more than twice. Skip activities that's already finishing
- // cleanly by itself.
- remove = false;
- } else if ((!r.hasSavedState() && !r.stateNotNeeded
- && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) {
- // Don't currently have state for the activity, or
- // it is finishing -- always remove it.
- remove = true;
- } else if (!r.mVisibleRequested && r.launchCount > 2
- && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
- // We have launched this activity too many times since it was
- // able to run, so give up and remove it.
- // (Note if the activity is visible, we don't remove the record.
- // We leave the dead window on the screen but the process will
- // not be restarted unless user explicitly tap on it.)
- remove = true;
- } else {
- // The process may be gone, but the activity lives on!
- remove = false;
- }
- if (remove) {
- if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
- "Removing activity " + r + " from stack "
- + ": hasSavedState=" + r.hasSavedState()
- + " stateNotNeeded=" + r.stateNotNeeded
- + " finishing=" + r.finishing
- + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
- if (!r.finishing || mIsProcessRemoved) {
- Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
- EventLogTags.writeWmFinishActivity(r.mUserId,
- System.identityHashCode(r), r.getTask().mTaskId,
- r.shortComponentName, "proc died without state saved");
- }
- } else {
- // We have the current state for this activity, so
- // it can be restarted later when needed.
- if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
- if (DEBUG_APP) Slog.v(TAG_APP,
- "Clearing app during removeHistory for activity " + r);
- r.app = null;
- // Set nowVisible to previous visible state. If the app was visible while
- // it died, we leave the dead window on screen so it's basically visible.
- // This is needed when user later tap on the dead window, we need to stop
- // other apps when user transfers focus to the restarted activity.
- r.nowVisible = r.mVisibleRequested;
- }
- r.cleanUp(true /* cleanServices */, true /* setState */);
- if (remove) {
- r.removeFromHistory("appDied");
- }
- }
- }
-
private final FindRootHelper mFindRootHelper = new FindRootHelper();
private class FindRootHelper {
private ActivityRecord mRoot;
@@ -3730,17 +3621,6 @@ class Task extends WindowContainer<WindowContainer> {
}
@Override
- public SurfaceControl getAnimationLeashParent() {
- if (WindowManagerService.sHierarchicalAnimations) {
- return super.getAnimationLeashParent();
- }
- // Currently, only the recents animation will create animation leashes for tasks. In this
- // case, reparent the task to the home animation layer while it is being animated to allow
- // the home activity to reorder the app windows relative to its own.
- return getAppAnimationLayer(ANIMATION_LAYER_HOME);
- }
-
- @Override
void resetSurfacePositionForAnimationLeash(SurfaceControl.Transaction t) {
if (isOrganized()) return;
super.resetSurfacePositionForAnimationLeash(t);
@@ -7178,9 +7058,8 @@ class Task extends WindowContainer<WindowContainer> {
/**
* Reset local parameters because an app's activity died.
* @param app The app of the activity that died.
- * @return result from removeHistoryRecordsForAppLocked.
*/
- boolean handleAppDied(WindowProcessController app) {
+ void handleAppDied(WindowProcessController app) {
if (mPausingActivity != null && mPausingActivity.app == app) {
if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
"App died while pausing: " + mPausingActivity);
@@ -7190,9 +7069,6 @@ class Task extends WindowContainer<WindowContainer> {
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
-
- mStackSupervisor.removeHistoryRecords(app);
- return mRemoveHistoryRecordsForApp.process(app);
}
boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index f37fe3a74f15..e24d185557e8 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -51,7 +51,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.logWithStack;
-import static com.android.server.wm.WindowManagerService.sHierarchicalAnimations;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import android.annotation.CallSuper;
@@ -858,6 +857,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
/**
+ * @return {@code true} when an application can override an app transition animation on this
+ * container.
+ */
+ boolean canCustomizeAppTransition() {
+ return !WindowManagerService.sDisableCustomTaskAnimationProperty;
+ }
+
+ /**
* @return {@code true} when this container or its related containers are running an
* animation, {@code false} otherwise.
*
@@ -2366,10 +2373,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
final Rect screenBounds = getAnimationBounds(appStackClipMode);
mTmpRect.set(screenBounds);
getAnimationPosition(mTmpPoint);
- if (!sHierarchicalAnimations) {
- // Non-hierarchical animation uses position in global coordinates.
- mTmpPoint.set(mTmpRect.left, mTmpRect.top);
- }
mTmpRect.offsetTo(0, 0);
final RemoteAnimationController controller =
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0b942ba094ff..ede92f0cad41 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -396,23 +396,22 @@ public class WindowManagerService extends IWindowManager.Stub
private static final boolean ALWAYS_KEEP_CURRENT = true;
/**
- * If set, new app transition framework which supports setting animation on any element
- * in a surface is used.
- * <p>
- * Only set this to non-zero once the new app transition framework is productionalized.
- * </p>
+ * Restrict ability of activities overriding transition animation in a way such that
+ * an activity can do it only when the transition happens within a same task.
+ *
+ * @see android.app.Activity#overridePendingTransition(int, int)
*/
- private static final String HIERARCHICAL_ANIMATIONS_PROPERTY =
- "persist.wm.hierarchical_animations";
-
- private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
- "ro.sf.disable_triple_buffer";
+ private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY =
+ "persist.wm.disable_custom_task_animation";
/**
- * @see #HIERARCHICAL_ANIMATIONS_PROPERTY
+ * @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY
*/
- static boolean sHierarchicalAnimations =
- SystemProperties.getBoolean(HIERARCHICAL_ANIMATIONS_PROPERTY, true);
+ static boolean sDisableCustomTaskAnimationProperty =
+ SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, false);
+
+ private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
+ "ro.sf.disable_triple_buffer";
static boolean sEnableTripleBuffering = !SystemProperties.getBoolean(
DISABLE_TRIPLE_BUFFERING_PROPERTY, false);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 6ba8769842f6..df59c56f5aff 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -177,8 +177,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// Whether this process has ever started a service with the BIND_INPUT_METHOD permission.
private volatile boolean mHasImeService;
- // all activities running in the process
+ /** All activities running in the process (exclude destroying). */
private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
+ /** The activities will be removed but still belong to this process. */
+ private ArrayList<ActivityRecord> mInactiveActivities;
// any tasks this process had run root activities in
private final ArrayList<Task> mRecentTasks = new ArrayList<>();
// The most recent top-most activity that was resumed in the process for pre-Q app.
@@ -635,21 +637,39 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return;
}
mActivities.add(r);
+ if (mInactiveActivities != null) {
+ mInactiveActivities.remove(r);
+ }
updateActivityConfigurationListener();
}
- void removeActivity(ActivityRecord r) {
+ /**
+ * Indicates that the given activity is no longer active in this process.
+ *
+ * @param r The running activity to be removed.
+ * @param keepAssociation {@code true} if the activity still belongs to this process but will
+ * be removed soon, e.g. destroying. From the perspective of process
+ * priority, the process is not important if it only contains activities
+ * that are being destroyed. But the association is still needed to
+ * ensure all activities are reachable from this process.
+ */
+ void removeActivity(ActivityRecord r, boolean keepAssociation) {
+ if (keepAssociation) {
+ if (mInactiveActivities == null) {
+ mInactiveActivities = new ArrayList<>();
+ mInactiveActivities.add(r);
+ } else if (!mInactiveActivities.contains(r)) {
+ mInactiveActivities.add(r);
+ }
+ } else if (mInactiveActivities != null) {
+ mInactiveActivities.remove(r);
+ }
mActivities.remove(r);
updateActivityConfigurationListener();
}
- void makeFinishingForProcessRemoved() {
- for (int i = mActivities.size() - 1; i >= 0; --i) {
- mActivities.get(i).makeFinishingLocked();
- }
- }
-
void clearActivities() {
+ mInactiveActivities = null;
mActivities.clear();
updateActivityConfigurationListener();
}
@@ -1142,6 +1162,47 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
mAtm.mH.sendMessage(m);
}
+ /**
+ * Clean up the activities belonging to this process.
+ *
+ * @return {@code true} if the process has any visible activity.
+ */
+ boolean handleAppDied() {
+ mAtm.mStackSupervisor.removeHistoryRecords(this);
+
+ final boolean isRemoved = isRemoved();
+ boolean hasVisibleActivities = false;
+ if (mInactiveActivities != null && !mInactiveActivities.isEmpty()) {
+ // Make sure that all activities in this process are handled.
+ mActivities.addAll(mInactiveActivities);
+ }
+ for (int i = mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mActivities.get(i);
+ if (r.mVisibleRequested || r.isVisible()) {
+ // While an activity launches a new activity, it's possible that the old activity
+ // is already requested to be hidden (mVisibleRequested=false), but this visibility
+ // is not yet committed, so isVisible()=true.
+ hasVisibleActivities = true;
+ }
+ if (isRemoved) {
+ // The package of the died process should be force-stopped, so make its activities
+ // as finishing to prevent the process from being started again if the next top (or
+ // being visible) activity also resides in the same process.
+ r.makeFinishingLocked();
+ }
+
+ final Task rootTask = r.getRootTask();
+ if (rootTask != null) {
+ rootTask.handleAppDied(this);
+ }
+ r.handleAppDied();
+ }
+ clearRecentTasks();
+ clearActivities();
+
+ return hasVisibleActivities;
+ }
+
void registerDisplayConfigurationListener(DisplayContent displayContent) {
if (displayContent == null) {
return;
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 10523a2adbb2..784366318319 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -239,9 +239,9 @@ public:
void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
uint32_t policyFlags) override;
void notifyConfigurationChanged(nsecs_t when) override;
- std::chrono::nanoseconds notifyAnr(const sp<InputApplicationHandle>& inputApplicationHandle,
- const sp<IBinder>& token,
- const std::string& reason) override;
+ std::chrono::nanoseconds notifyAnr(
+ const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
+ const sp<IBinder>& token, const std::string& reason) override;
void notifyInputChannelBroken(const sp<IBinder>& token) override;
void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) override;
bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override;
@@ -682,8 +682,8 @@ void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
}
-static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
- const sp<InputApplicationHandle>& inputApplicationHandle) {
+static jobject getInputApplicationHandleObjLocalRef(
+ JNIEnv* env, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
if (inputApplicationHandle == nullptr) {
return nullptr;
}
@@ -694,8 +694,8 @@ static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
}
std::chrono::nanoseconds NativeInputManager::notifyAnr(
- const sp<InputApplicationHandle>& inputApplicationHandle, const sp<IBinder>& token,
- const std::string& reason) {
+ const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
+ const sp<IBinder>& token, const std::string& reason) {
#if DEBUG_INPUT_DISPATCHER_POLICY
ALOGD("notifyANR");
#endif
@@ -780,8 +780,12 @@ void NativeInputManager::displayRemoved(JNIEnv* env, int32_t displayId) {
void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
jobject applicationHandleObj) {
- sp<InputApplicationHandle> applicationHandle =
+ if (!applicationHandleObj) {
+ return;
+ }
+ std::shared_ptr<InputApplicationHandle> applicationHandle =
android_view_InputApplicationHandle_getHandle(env, applicationHandleObj);
+ applicationHandle->updateInfo();
mInputManager->getDispatcher()->setFocusedApplication(displayId, applicationHandle);
}
diff --git a/services/core/jni/stats/PowerStatsPuller.cpp b/services/core/jni/stats/PowerStatsPuller.cpp
index d8f6faac0ffb..7f788c226c7b 100644
--- a/services/core/jni/stats/PowerStatsPuller.cpp
+++ b/services/core/jni/stats/PowerStatsPuller.cpp
@@ -135,16 +135,11 @@ AStatsManager_PullAtomCallbackReturn PowerStatsPuller::Pull(int32_t atomTag,
}
const RailInfo& rail = gRailInfo[energyData.index];
- AStatsEvent* event =
- AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(
- event,
- android::util::ON_DEVICE_POWER_MEASUREMENT);
- AStatsEvent_writeString(event, rail.subsysName.c_str());
- AStatsEvent_writeString(event, rail.railName.c_str());
- AStatsEvent_writeInt64(event, energyData.timestamp);
- AStatsEvent_writeInt64(event, energyData.energy);
- AStatsEvent_build(event);
+ android::util::addAStatsEvent(
+ data,
+ android::util::ON_DEVICE_POWER_MEASUREMENT,
+ rail.subsysName.c_str(), rail.railName.c_str(),
+ energyData.timestamp, energyData.energy);
ALOGV("power.stat: %s.%s: %llu, %llu",
rail.subsysName.c_str(), rail.railName.c_str(),
diff --git a/services/core/jni/stats/SubsystemSleepStatePuller.cpp b/services/core/jni/stats/SubsystemSleepStatePuller.cpp
index 45afb5eb7aa9..1ba98ef8dab7 100644
--- a/services/core/jni/stats/SubsystemSleepStatePuller.cpp
+++ b/services/core/jni/stats/SubsystemSleepStatePuller.cpp
@@ -194,17 +194,13 @@ static AStatsManager_PullAtomCallbackReturn getIPowerStatsDataLocked(int32_t ato
}
for (auto result : results) {
for (auto stateResidency : result.stateResidencyData) {
- AStatsEvent* event = AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(event, android::util::SUBSYSTEM_SLEEP_STATE);
- AStatsEvent_writeString(event,
- gEntityNames.at(result.powerEntityId).c_str());
- AStatsEvent_writeString(event,
- gStateNames.at(result.powerEntityId)
- .at(stateResidency.powerEntityStateId)
- .c_str());
- AStatsEvent_writeInt64(event, stateResidency.totalStateEntryCount);
- AStatsEvent_writeInt64(event, stateResidency.totalTimeInStateMs);
- AStatsEvent_build(event);
+ android::util::addAStatsEvent(data, android::util::SUBSYSTEM_SLEEP_STATE,
+ gEntityNames.at(result.powerEntityId).c_str(),
+ gStateNames.at(result.powerEntityId)
+ .at(stateResidency.powerEntityStateId)
+ .c_str(),
+ stateResidency.totalStateEntryCount,
+ stateResidency.totalTimeInStateMs);
}
}
success = true;
@@ -259,26 +255,21 @@ static AStatsManager_PullAtomCallbackReturn getIPowerDataLocked(int32_t atomTag,
for (size_t i = 0; i < states.size(); i++) {
const PowerStatePlatformSleepState& state = states[i];
- AStatsEvent* event = AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(event, android::util::SUBSYSTEM_SLEEP_STATE);
- AStatsEvent_writeString(event, state.name.c_str());
- AStatsEvent_writeString(event, "");
- AStatsEvent_writeInt64(event, state.totalTransitions);
- AStatsEvent_writeInt64(event, state.residencyInMsecSinceBoot);
- AStatsEvent_build(event);
+ android::util::addAStatsEvent(data, android::util::SUBSYSTEM_SLEEP_STATE,
+ state.name.c_str(), "",
+ state.totalTransitions,
+ state.residencyInMsecSinceBoot);
ALOGV("powerstate: %s, %lld, %lld, %d", state.name.c_str(),
(long long)state.residencyInMsecSinceBoot,
(long long)state.totalTransitions,
state.supportedOnlyInSuspend ? 1 : 0);
for (const auto& voter : state.voters) {
- AStatsEvent* event = AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(event, android::util::SUBSYSTEM_SLEEP_STATE);
- AStatsEvent_writeString(event, state.name.c_str());
- AStatsEvent_writeString(event, voter.name.c_str());
- AStatsEvent_writeInt64(event, voter.totalNumberOfTimesVotedSinceBoot);
- AStatsEvent_writeInt64(event, voter.totalTimeInMsecVotedForSinceBoot);
- AStatsEvent_build(event);
+ android::util::addAStatsEvent(data,
+ android::util::SUBSYSTEM_SLEEP_STATE,
+ state.name.c_str(), voter.name.c_str(),
+ voter.totalNumberOfTimesVotedSinceBoot,
+ voter.totalTimeInMsecVotedForSinceBoot);
ALOGV("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
voter.name.c_str(),
@@ -305,14 +296,13 @@ static AStatsManager_PullAtomCallbackReturn getIPowerDataLocked(int32_t atomTag,
for (size_t j = 0; j < subsystem.states.size(); j++) {
const PowerStateSubsystemSleepState& state =
subsystem.states[j];
- AStatsEvent* event = AStatsEventList_addStatsEvent(data);
- AStatsEvent_setAtomId(event,
- android::util::SUBSYSTEM_SLEEP_STATE);
- AStatsEvent_writeString(event, subsystem.name.c_str());
- AStatsEvent_writeString(event, state.name.c_str());
- AStatsEvent_writeInt64(event, state.totalTransitions);
- AStatsEvent_writeInt64(event, state.residencyInMsecSinceBoot);
- AStatsEvent_build(event);
+ android::util::
+ addAStatsEvent(data,
+ android::util::SUBSYSTEM_SLEEP_STATE,
+ subsystem.name.c_str(),
+ state.name.c_str(),
+ state.totalTransitions,
+ state.residencyInMsecSinceBoot);
ALOGV("subsystemstate: %s, %s, %lld, %lld, %lld",
subsystem.name.c_str(), state.name.c_str(),
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7ec819f13e96..9a2bef85860f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -290,6 +290,7 @@ import com.android.server.LockGuard;
import com.android.server.PersistentDataBlockManagerInternal;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.net.NetworkPolicyManagerInternal;
@@ -775,18 +776,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@Override
- public void onStartUser(int userHandle) {
- mService.handleStartUser(userHandle);
+ public void onUserStarting(@NonNull TargetUser user) {
+ mService.handleStartUser(user.getUserIdentifier());
}
@Override
- public void onUnlockUser(int userHandle) {
- mService.handleUnlockUser(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mService.handleUnlockUser(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- mService.handleStopUser(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mService.handleStopUser(user.getUserIdentifier());
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ae6ccda71558..c11c4b2e25c1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -152,6 +152,7 @@ import com.android.server.policy.role.LegacyRoleResolutionPolicy;
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import com.android.server.power.ThermalManagerService;
+import com.android.server.profcollect.ProfcollectForwardingService;
import com.android.server.recoverysystem.RecoverySystemService;
import com.android.server.restrictions.RestrictionsManagerService;
import com.android.server.role.RoleManagerService;
@@ -1229,6 +1230,12 @@ public final class SystemServer {
mSystemServiceManager.startService(IorapForwardingService.class);
t.traceEnd();
+ if (Build.IS_DEBUGGABLE) {
+ t.traceBegin("ProfcollectForwardingService");
+ mSystemServiceManager.startService(ProfcollectForwardingService.class);
+ t.traceEnd();
+ }
+
t.traceBegin("SignedConfigService");
SignedConfigService.registerUpdateReceiver(mSystemContext);
t.traceEnd();
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 51478b365715..2cfdf3fd4f6f 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -16,6 +16,7 @@
package com.android.server.midi;
+import android.annotation.NonNull;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
@@ -47,8 +48,8 @@ import android.util.Log;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.XmlUtils;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import org.xmlpull.v1.XmlPullParser;
@@ -75,8 +76,8 @@ public class MidiService extends IMidiManager.Stub {
}
@Override
- public void onUnlockUser(int userHandle) {
- if (userHandle == UserHandle.USER_SYSTEM) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ if (user.getUserIdentifier() == UserHandle.USER_SYSTEM) {
mMidiService.onUnlockUser();
}
}
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index d064f7ee62c3..1cdcbd87c1f5 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -72,6 +72,7 @@ import com.android.internal.util.Preconditions;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -101,13 +102,13 @@ public final class PrintManagerService extends SystemService {
}
@Override
- public void onUnlockUser(int userHandle) {
- mPrintManagerImpl.handleUserUnlocked(userHandle);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mPrintManagerImpl.handleUserUnlocked(user.getUserIdentifier());
}
@Override
- public void onStopUser(int userHandle) {
- mPrintManagerImpl.handleUserStopped(userHandle);
+ public void onUserStopping(@NonNull TargetUser user) {
+ mPrintManagerImpl.handleUserStopped(user.getUserIdentifier());
}
class PrintManagerImpl extends IPrintManager.Stub {
diff --git a/services/profcollect/Android.bp b/services/profcollect/Android.bp
new file mode 100644
index 000000000000..68fba5508b58
--- /dev/null
+++ b/services/profcollect/Android.bp
@@ -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.
+
+filegroup {
+ name: "services.profcollect-javasources",
+ srcs: ["src/**/*.java"],
+ path: "src",
+ visibility: ["//frameworks/base/services"],
+}
+
+filegroup {
+ name: "services.profcollect-sources",
+ srcs: [
+ ":services.profcollect-javasources",
+ ":profcollectd_aidl",
+ ],
+ visibility: ["//frameworks/base/services:__subpackages__"],
+}
+
+java_library_static {
+ name: "services.profcollect",
+ srcs: [":services.profcollect-sources"],
+ libs: ["services.core"],
+}
diff --git a/services/profcollect/OWNERS b/services/profcollect/OWNERS
new file mode 100644
index 000000000000..b380e39529e3
--- /dev/null
+++ b/services/profcollect/OWNERS
@@ -0,0 +1,3 @@
+srhines@google.com
+yabinc@google.com
+yikong@google.com
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
new file mode 100644
index 000000000000..bc75dcd91813
--- /dev/null
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -0,0 +1,196 @@
+/**
+ * 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.profcollect;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder.DeathRecipient;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.server.IoThread;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.wm.ActivityMetricsLaunchObserver;
+import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * System-server-local proxy into the {@code IProfcollectd} native service.
+ */
+public final class ProfcollectForwardingService extends SystemService {
+ public static final String LOG_TAG = "ProfcollectForwardingService";
+
+ private IProfCollectd mIProfcollect;
+ private ProfcollectForwardingService mSelfService;
+ private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper());
+
+ public ProfcollectForwardingService(Context context) {
+ super(context);
+
+ if (mSelfService != null) {
+ throw new AssertionError("only one service instance allowed");
+ }
+ mSelfService = this;
+ }
+
+ @Override
+ public void onStart() {
+ Log.i(LOG_TAG, "Profcollect forwarding service start");
+ connectNativeService();
+ if (mIProfcollect == null) {
+ return;
+ }
+ if (serviceHasSupportedTraceProvider()) {
+ registerObservers();
+ }
+ }
+
+ private boolean serviceHasSupportedTraceProvider() {
+ if (mIProfcollect == null) {
+ return false;
+ }
+ try {
+ return !mIProfcollect.GetSupportedProvider().isEmpty();
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, e.getMessage());
+ return false;
+ }
+ }
+
+ private boolean tryConnectNativeService() {
+ if (connectNativeService()) {
+ return true;
+ }
+ // Cannot connect to the native service at this time, retry after a short delay.
+ mHandler.sendEmptyMessageDelayed(ProfcollectdHandler.MESSAGE_BINDER_CONNECT, 5000);
+ return false;
+ }
+
+ private boolean connectNativeService() {
+ try {
+ IProfCollectd profcollectd =
+ IProfCollectd.Stub.asInterface(
+ ServiceManager.getServiceOrThrow("profcollectd"));
+ profcollectd.asBinder().linkToDeath(new ProfcollectdDeathRecipient(), /*flags*/0);
+ mIProfcollect = profcollectd;
+ return true;
+ } catch (ServiceManager.ServiceNotFoundException | RemoteException e) {
+ Log.w(LOG_TAG, "Failed to connect profcollectd binder service.");
+ return false;
+ }
+ }
+
+ private class ProfcollectdHandler extends Handler {
+ public ProfcollectdHandler(Looper looper) {
+ super(looper);
+ }
+
+ public static final int MESSAGE_BINDER_CONNECT = 0;
+
+ @Override
+ public void handleMessage(android.os.Message message) {
+ switch (message.what) {
+ case MESSAGE_BINDER_CONNECT:
+ connectNativeService();
+ break;
+ default:
+ throw new AssertionError("Unknown message: " + message.toString());
+ }
+ }
+ }
+
+ private class ProfcollectdDeathRecipient implements DeathRecipient {
+ @Override
+ public void binderDied() {
+ Log.w(LOG_TAG, "profcollectd has died");
+
+ mIProfcollect = null;
+ tryConnectNativeService();
+ }
+ }
+
+ // Event observers
+ private void registerObservers() {
+ registerAppLaunchObserver();
+ }
+
+ private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver();
+ private void registerAppLaunchObserver() {
+ ActivityTaskManagerInternal atmInternal =
+ LocalServices.getService(ActivityTaskManagerInternal.class);
+ ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
+ atmInternal.getLaunchObserverRegistry();
+ launchObserverRegistry.registerLaunchObserver(mAppLaunchObserver);
+ }
+
+ private void traceOnAppStart(String packageName) {
+ if (mIProfcollect == null) {
+ return;
+ }
+
+ // Sample for a fraction of app launches.
+ int traceFrequency = SystemProperties.getInt("profcollectd.applaunch_trace_freq", 2);
+ int randomNum = ThreadLocalRandom.current().nextInt(100);
+ if (randomNum < traceFrequency) {
+ try {
+ Log.i(LOG_TAG, "Tracing on app launch event: " + packageName);
+ mIProfcollect.TraceOnce("applaunch");
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, e.getMessage());
+ }
+ }
+ }
+
+ private class AppLaunchObserver implements ActivityMetricsLaunchObserver {
+ @Override
+ public void onIntentStarted(Intent intent, long timestampNanos) {
+ traceOnAppStart(intent.getPackage());
+ }
+
+ @Override
+ public void onIntentFailed() {
+ // Ignored
+ }
+
+ @Override
+ public void onActivityLaunched(byte[] activity, int temperature) {
+ // Ignored
+ }
+
+ @Override
+ public void onActivityLaunchCancelled(byte[] abortingActivity) {
+ // Ignored
+ }
+
+ @Override
+ public void onActivityLaunchFinished(byte[] finalActivity, long timestampNanos) {
+ // Ignored
+ }
+
+ @Override
+ public void onReportFullyDrawn(byte[] activity, long timestampNanos) {
+ // Ignored
+ }
+ }
+}
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
index 4a73efe25fdb..cd9b6aca72e0 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
@@ -38,7 +38,6 @@ import static org.testng.Assert.expectThrows;
import android.annotation.UserIdInt;
import android.app.Application;
-import android.app.backup.BackupManager;
import android.app.backup.BackupManager.OperationType;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
@@ -46,6 +45,7 @@ import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.ISelectBackupTransportCallback;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.UserInfo;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -54,6 +54,7 @@ import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
import android.util.SparseArray;
+import com.android.server.SystemService.TargetUser;
import com.android.server.backup.testing.TransportData;
import com.android.server.testing.shadows.ShadowApplicationPackageManager;
import com.android.server.testing.shadows.ShadowBinder;
@@ -1601,7 +1602,7 @@ public class BackupManagerServiceRoboTest {
BackupManagerService.Lifecycle lifecycle =
new BackupManagerService.Lifecycle(mContext, backupManagerService);
- lifecycle.onUnlockUser(UserHandle.USER_SYSTEM);
+ lifecycle.onUserUnlocking(new TargetUser(new UserInfo(UserHandle.USER_SYSTEM, null, 0)));
verify(backupManagerService).onUnlockUser(UserHandle.USER_SYSTEM);
}
@@ -1613,7 +1614,7 @@ public class BackupManagerServiceRoboTest {
BackupManagerService.Lifecycle lifecycle =
new BackupManagerService.Lifecycle(mContext, backupManagerService);
- lifecycle.onStopUser(UserHandle.USER_SYSTEM);
+ lifecycle.onUserStopping(new TargetUser(new UserInfo(UserHandle.USER_SYSTEM, null, 0)));
verify(backupManagerService).onStopUser(UserHandle.USER_SYSTEM);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 8ccaeddc8355..2f5e8839504b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -247,7 +247,7 @@ public class AppStateTrackerTest {
.thenAnswer(inv -> getPowerSaveState());
when(mMockAppOpsManager.getPackagesForOps(
any(int[].class)
- )).thenAnswer(mGetPackagesForOps);
+ )).thenAnswer(mGetPackagesForOps);
mMockContentResolver = new MockContentResolver();
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
@@ -447,7 +447,7 @@ public class AppStateTrackerTest {
areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
- // Clear the app ops and update the whitelist.
+ // Clear the app ops and update the exemption list.
setAppOps(UID_1, PACKAGE_1, false);
setAppOps(UID_10_2, PACKAGE_2, false);
@@ -462,7 +462,8 @@ public class AppStateTrackerTest {
areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {}, new int[] {UID_2});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_1}, new int[] {},
+ new int[] {UID_2});
areRestricted(instance, UID_1, PACKAGE_1, NONE);
areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
@@ -487,24 +488,25 @@ public class AppStateTrackerTest {
areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
- assertTrue(instance.isUidPowerSaveWhitelisted(UID_1));
- assertTrue(instance.isUidPowerSaveWhitelisted(UID_10_1));
- assertFalse(instance.isUidPowerSaveWhitelisted(UID_2));
- assertFalse(instance.isUidPowerSaveWhitelisted(UID_10_2));
+ assertTrue(instance.isUidPowerSaveExempt(UID_1));
+ assertTrue(instance.isUidPowerSaveExempt(UID_10_1));
+ assertFalse(instance.isUidPowerSaveExempt(UID_2));
+ assertFalse(instance.isUidPowerSaveExempt(UID_10_2));
- assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_1));
- assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_10_1));
- assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_2));
- assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_10_2));
+ assertFalse(instance.isUidTempPowerSaveExempt(UID_1));
+ assertFalse(instance.isUidTempPowerSaveExempt(UID_10_1));
+ assertTrue(instance.isUidTempPowerSaveExempt(UID_2));
+ assertTrue(instance.isUidTempPowerSaveExempt(UID_10_2));
}
@Test
- public void testPowerSaveUserWhitelist() throws Exception {
+ public void testPowerSaveUserExemptionList() throws Exception {
final AppStateTrackerTestable instance = newInstance();
- instance.setPowerSaveWhitelistAppIds(new int[] {}, new int[] {UID_1, UID_2}, new int[] {});
- assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_1));
- assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_2));
- assertFalse(instance.isUidPowerSaveUserWhitelisted(UID_3));
+ instance.setPowerSaveExemptionListAppIds(new int[] {}, new int[] {UID_1, UID_2},
+ new int[] {});
+ assertTrue(instance.isUidPowerSaveUserExempt(UID_1));
+ assertTrue(instance.isUidPowerSaveUserExempt(UID_2));
+ assertFalse(instance.isUidPowerSaveUserExempt(UID_3));
}
@Test
@@ -909,9 +911,10 @@ public class AppStateTrackerTest {
reset(l);
// -------------------------------------------------------------------------
- // Tests with system/user/temp whitelist.
+ // Tests with system/user/temp exemption list.
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_1, UID_2}, new int[] {},
+ new int[] {});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -923,7 +926,7 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -935,8 +938,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- // Update temp whitelist.
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
+ // Update temp exemption list.
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
new int[] {UID_1, UID_3});
waitUntilMainHandlerDrain();
@@ -949,7 +952,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
+ new int[] {UID_3});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -975,10 +979,11 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_1, UID_2}, new int[] {},
+ new int[] {});
waitUntilMainHandlerDrain();
- // Called once for updating all whitelist and once for updating temp whitelist
+ // Called once for updating all exemption list and once for updating temp exemption list
verify(l, times(2)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
@@ -988,7 +993,7 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -1000,8 +1005,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- // Update temp whitelist.
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
+ // Update temp exemption list.
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
new int[] {UID_1, UID_3});
waitUntilMainHandlerDrain();
@@ -1014,7 +1019,8 @@ public class AppStateTrackerTest {
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
+ instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
+ new int[] {UID_3});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -1254,7 +1260,7 @@ public class AppStateTrackerTest {
.mapToInt(Integer::intValue).toArray();
}
- static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) {
+ static boolean isAnyAppIdUnexemptSlow(int[] prevArray, int[] newArray) {
Arrays.sort(newArray); // Just in case...
for (int p : prevArray) {
if (Arrays.binarySearch(newArray, p) < 0) {
@@ -1264,31 +1270,31 @@ public class AppStateTrackerTest {
return false;
}
- private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) {
+ private void checkAnyAppIdUnexempt(int[] prevArray, int[] newArray, boolean expected) {
assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
- expected, AppStateTrackerImpl.isAnyAppIdUnwhitelisted(prevArray, newArray));
+ expected, AppStateTrackerImpl.isAnyAppIdUnexempt(prevArray, newArray));
- // Also test isAnyAppIdUnwhitelistedSlow.
+ // Also test isAnyAppIdUnexempt.
assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
- expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray));
+ expected, isAnyAppIdUnexemptSlow(prevArray, newArray));
}
@Test
- public void isAnyAppIdUnwhitelisted() {
- checkAnyAppIdUnwhitelisted(array(), array(), false);
-
- checkAnyAppIdUnwhitelisted(array(1), array(), true);
- checkAnyAppIdUnwhitelisted(array(1), array(1), false);
- checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false);
- checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
- checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
-
- checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true);
- checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true);
- checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false);
- checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true);
- checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
- checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
+ public void isAnyAppIdUnexempt() {
+ checkAnyAppIdUnexempt(array(), array(), false);
+
+ checkAnyAppIdUnexempt(array(1), array(), true);
+ checkAnyAppIdUnexempt(array(1), array(1), false);
+ checkAnyAppIdUnexempt(array(1), array(0, 1), false);
+ checkAnyAppIdUnexempt(array(1), array(0, 1, 2), false);
+ checkAnyAppIdUnexempt(array(1), array(0, 1, 2), false);
+
+ checkAnyAppIdUnexempt(array(1, 2, 10), array(), true);
+ checkAnyAppIdUnexempt(array(1, 2, 10), array(1, 2), true);
+ checkAnyAppIdUnexempt(array(1, 2, 10), array(1, 2, 10), false);
+ checkAnyAppIdUnexempt(array(1, 2, 10), array(2, 10), true);
+ checkAnyAppIdUnexempt(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
+ checkAnyAppIdUnexempt(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
// Random test
int trueCount = 0;
@@ -1297,8 +1303,8 @@ public class AppStateTrackerTest {
final int[] array1 = makeRandomArray();
final int[] array2 = makeRandomArray();
- final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2);
- final boolean actual = AppStateTrackerImpl.isAnyAppIdUnwhitelisted(array1, array2);
+ final boolean expected = isAnyAppIdUnexemptSlow(array1, array2);
+ final boolean actual = AppStateTrackerImpl.isAnyAppIdUnexempt(array1, array2);
assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
expected, actual);
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 6f37ff5ef329..c91bb93fc559 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -28,11 +28,13 @@ import static org.mockito.Mockito.when;
import android.app.StatusBarManager;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
import android.os.Looper;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
+import android.telecom.TelecomManager;
import android.test.mock.MockContentResolver;
import android.util.MutableBoolean;
import android.view.KeyEvent;
@@ -80,6 +82,7 @@ public class GestureLauncherServiceTest {
private @Mock Context mContext;
private @Mock Resources mResources;
private @Mock StatusBarManagerInternal mStatusBarManagerInternal;
+ private @Mock TelecomManager mTelecomManager;
private @Mock MetricsLogger mMetricsLogger;
private MockContentResolver mContentResolver;
private GestureLauncherService mGestureLauncherService;
@@ -104,6 +107,8 @@ public class GestureLauncherServiceTest {
mContentResolver = new MockContentResolver(mContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mContext.getSystemService(Context.TELECOM_SERVICE)).thenReturn(mTelecomManager);
+ when(mTelecomManager.createLaunchEmergencyDialerIntent(null)).thenReturn(new Intent());
mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger);
}
@@ -176,6 +181,13 @@ public class GestureLauncherServiceTest {
}
@Test
+ public void testHandlePanicGesture_userSetupComplete() {
+ withUserSetupCompleteValue(true);
+
+ assertTrue(mGestureLauncherService.handlePanicButtonGesture());
+ }
+
+ @Test
public void testHandleCameraLaunchGesture_userSetupNotComplete() {
withUserSetupCompleteValue(false);
@@ -184,6 +196,13 @@ public class GestureLauncherServiceTest {
}
@Test
+ public void testHandlePanicGesture_userSetupNotComplete() {
+ withUserSetupCompleteValue(false);
+
+ assertFalse(mGestureLauncherService.handlePanicButtonGesture());
+ }
+
+ @Test
public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() {
withCameraDoubleTapPowerEnableConfigValue(true);
withCameraDoubleTapPowerDisableSettingValue(0);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index a9f2e4a50ded..57bfbf33d680 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -95,12 +96,15 @@ public class FullScreenMagnificationControllerTest {
ValueAnimator mMockValueAnimator;
ValueAnimator.AnimatorUpdateListener mTargetAnimationListener;
+ ValueAnimator.AnimatorListener mStateListener;
FullScreenMagnificationController mFullScreenMagnificationController;
+ Runnable mEndCallback;
@Before
public void setUp() {
Looper looper = InstrumentationRegistry.getContext().getMainLooper();
+ mEndCallback = Mockito.mock(Runnable.class);
// Pretending ID of the Thread associated with looper as main thread ID in controller
when(mMockContext.getMainLooper()).thenReturn(looper);
when(mMockControllerCtx.getContext()).thenReturn(mMockContext);
@@ -319,6 +323,7 @@ public class FullScreenMagnificationControllerTest {
for (int i = 0; i < DISPLAY_COUNT; i++) {
setScaleAndCenter_animated_stateChangesAndAnimationHappens(i);
resetMockWindowManager();
+ Mockito.reset(mEndCallback);
}
}
@@ -331,7 +336,7 @@ public class FullScreenMagnificationControllerTest {
MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, scale,
- newCenter.x, newCenter.y, true, SERVICE_ID_1));
+ newCenter.x, newCenter.y, mEndCallback, SERVICE_ID_1));
mMessageCapturingHandler.sendAllMessages();
assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
@@ -358,7 +363,33 @@ public class FullScreenMagnificationControllerTest {
Mockito.reset(mMockWindowManager);
when(mMockValueAnimator.getAnimatedFraction()).thenReturn(1.0f);
mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+ mStateListener.onAnimationEnd(mMockValueAnimator);
verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(endSpec)));
+ verify(mEndCallback).run();
+ }
+
+ @Test
+ public void testSetScaleAndCenterWithAnimation_sameSpec_noAnimationButInvokeEndCallback() {
+ for (int i = 0; i < DISPLAY_COUNT; i++) {
+ setScaleAndCenter_sameSpec_noAnimationButInvokeEndCallback(i);
+ Mockito.reset(mEndCallback);
+ }
+ }
+
+ private void setScaleAndCenter_sameSpec_noAnimationButInvokeEndCallback(int displayId) {
+ register(displayId);
+ final PointF center = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+ final float targetScale = 2.0f;
+ assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
+ targetScale, center.x, center.y, false, SERVICE_ID_1));
+ mMessageCapturingHandler.sendAllMessages();
+
+ assertFalse(mFullScreenMagnificationController.setScaleAndCenter(displayId,
+ targetScale, center.x, center.y, mEndCallback, SERVICE_ID_1));
+ mMessageCapturingHandler.sendAllMessages();
+
+ verify(mMockValueAnimator, never()).start();
+ verify(mEndCallback).run();
}
@Test
@@ -639,6 +670,69 @@ public class FullScreenMagnificationControllerTest {
}
@Test
+ public void testReset_notMagnifying_noStateChangeButInvokeCallback() {
+ for (int i = 0; i < DISPLAY_COUNT; i++) {
+ reset_notMagnifying_noStateChangeButInvokeCallback(i);
+ Mockito.reset(mEndCallback);
+ }
+ }
+
+ private void reset_notMagnifying_noStateChangeButInvokeCallback(int displayId) {
+ register(displayId);
+
+ assertFalse(mFullScreenMagnificationController.reset(displayId, mEndCallback));
+ mMessageCapturingHandler.sendAllMessages();
+
+ verify(mMockAms, never()).notifyMagnificationChanged(eq(displayId),
+ any(Region.class), anyFloat(), anyFloat(), anyFloat());
+ verify(mEndCallback).run();
+ }
+
+ @Test
+ public void testReset_Magnifying_resetsMagnificationAndInvokeLastEndCallback() {
+ for (int i = 0; i < DISPLAY_COUNT; i++) {
+ reset_Magnifying_resetsMagnificationAndInvokeLastEndCallback(i);
+ }
+ }
+
+ private void reset_Magnifying_resetsMagnificationAndInvokeLastEndCallback(int displayId) {
+ register(displayId);
+ float scale = 2.5f;
+ PointF firstCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+ assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
+ scale, firstCenter.x, firstCenter.y, mEndCallback, SERVICE_ID_1));
+ mMessageCapturingHandler.sendAllMessages();
+ Mockito.reset(mMockValueAnimator);
+ // Stubs the logic after the animation is started.
+ doAnswer(invocation -> {
+ mStateListener.onAnimationEnd(mMockValueAnimator);
+ return null;
+ }).when(mMockValueAnimator).cancel();
+ when(mMockValueAnimator.isRunning()).thenReturn(true);
+ // Intermediate point
+ float fraction = 0.33f;
+ when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction);
+ mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+ Runnable lastEndCallback = Mockito.mock(Runnable.class);
+
+ assertTrue(mFullScreenMagnificationController.reset(displayId, lastEndCallback));
+ mMessageCapturingHandler.sendAllMessages();
+
+ // Verify expected actions.
+ verify(mEndCallback, never()).run();
+ verify(mMockValueAnimator).start();
+ verify(mMockValueAnimator).cancel();
+
+ // Fast-forward the animation to the end.
+ when(mMockValueAnimator.getAnimatedFraction()).thenReturn(1.0f);
+ mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+ mStateListener.onAnimationEnd(mMockValueAnimator);
+
+ assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_0));
+ verify(lastEndCallback).run();
+ }
+
+ @Test
public void testTurnScreenOff_resetsMagnification() {
register(DISPLAY_0);
register(DISPLAY_1);
@@ -1043,6 +1137,10 @@ public class FullScreenMagnificationControllerTest {
ArgumentCaptor.forClass(ValueAnimator.AnimatorUpdateListener.class);
verify(mMockValueAnimator).addUpdateListener(listenerArgumentCaptor.capture());
mTargetAnimationListener = listenerArgumentCaptor.getValue();
+ ArgumentCaptor<ValueAnimator.AnimatorListener> animatorListenerArgumentCaptor =
+ ArgumentCaptor.forClass(ValueAnimator.AnimatorListener.class);
+ verify(mMockValueAnimator).addListener(animatorListenerArgumentCaptor.capture());
+ mStateListener = animatorListenerArgumentCaptor.getValue();
Mockito.reset(mMockValueAnimator); // Ignore other initialization
}
diff --git a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
index 0dfdd4862d2b..922d71554426 100644
--- a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
@@ -99,6 +99,7 @@ public class AttentionManagerServiceTest {
AttentionCheck attentionCheck = new AttentionCheck(mMockAttentionCallbackInternal,
mSpyAttentionManager);
mSpyAttentionManager.mCurrentAttentionCheck = attentionCheck;
+ mSpyAttentionManager.mService = new MockIAttentionService();
}
@Test
@@ -115,6 +116,7 @@ public class AttentionManagerServiceTest {
@Test
public void testCheckAttention_returnFalseWhenPowerManagerNotInteract() throws RemoteException {
+ doReturn(true).when(mSpyAttentionManager).isAttentionServiceSupported();
doReturn(false).when(mMockIPowerManager).isInteractive();
AttentionCallbackInternal callback = Mockito.mock(AttentionCallbackInternal.class);
assertThat(mSpyAttentionManager.checkAttention(mTimeout, callback)).isFalse();
@@ -122,9 +124,11 @@ public class AttentionManagerServiceTest {
@Test
public void testCheckAttention_callOnSuccess() throws RemoteException {
- doReturn(true).when(mSpyAttentionManager).isServiceEnabled();
+ doReturn(true).when(mSpyAttentionManager).isAttentionServiceSupported();
+ doReturn(true).when(mSpyAttentionManager).isServiceAvailable();
doReturn(true).when(mMockIPowerManager).isInteractive();
doNothing().when(mSpyAttentionManager).freeIfInactiveLocked();
+ mSpyAttentionManager.mCurrentAttentionCheck = null;
AttentionCallbackInternal callback = Mockito.mock(AttentionCallbackInternal.class);
mSpyAttentionManager.checkAttention(mTimeout, callback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
new file mode 100644
index 000000000000..dad360d40515
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.biometrics.sensors;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@SmallTest
+public class BiometricSchedulerTest {
+
+ private static final String TAG = "BiometricSchedulerTest";
+
+ private BiometricScheduler mScheduler;
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private ClientMonitor.LazyDaemon<Object> mLazyDaemon;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */);
+ }
+
+ @Test
+ public void testClientDuplicateFinish_ignoredBySchedulerAndDoesNotCrash() {
+ final ClientMonitor<Object> client1 = new TestClientMonitor(mContext, mLazyDaemon);
+ final ClientMonitor<Object> client2 = new TestClientMonitor(mContext, mLazyDaemon);
+ mScheduler.scheduleClientMonitor(client1);
+ mScheduler.scheduleClientMonitor(client2);
+
+ client1.mFinishCallback.onClientFinished(client1, true /* success */);
+ client1.mFinishCallback.onClientFinished(client1, true /* success */);
+ }
+
+ private static class TestClientMonitor extends ClientMonitor<Object> {
+
+ public TestClientMonitor(@NonNull Context context, @NonNull LazyDaemon<Object> lazyDaemon) {
+ super(context, lazyDaemon, null /* token */, null /* listener */, 0 /* userId */,
+ TAG, 0 /* cookie */, 0 /* sensorId */, 0 /* statsModality */,
+ 0 /* statsAction */, 0 /* statsClient */);
+ }
+
+ @Override
+ public void unableToStart() {
+
+ }
+
+ @Override
+ protected void startHalOperation() {
+
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 50086affcbc5..870a27417cd2 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -144,6 +144,26 @@ public class ActiveSourceActionTest {
}
@Test
+ public void playbackDevice_updatesActiveSourceState() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ HdmiCecFeatureAction action = new com.android.server.hdmi.ActiveSourceAction(
+ playbackDevice, ADDR_TV);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ assertThat(playbackDevice.getActiveSource().logicalAddress).isEqualTo(
+ playbackDevice.mAddress);
+ assertThat(playbackDevice.getActiveSource().physicalAddress).isEqualTo(mPhysicalAddress);
+ assertThat(playbackDevice.mIsActiveSource).isTrue();
+ }
+
+ @Test
public void audioDevice_sendsActiveSource_noMenuStatus() {
HdmiCecLocalDeviceAudioSystem audioDevice = new HdmiCecLocalDeviceAudioSystem(
mHdmiControlService);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 32054632dafc..960a7ab52c22 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -275,7 +275,6 @@ public class HdmiCecLocalDevicePlaybackTest {
}
@Test
- @Ignore("b/120845532")
public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
mHdmiControlService.setSystemAudioActivated(false);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
@@ -287,7 +286,6 @@ public class HdmiCecLocalDevicePlaybackTest {
}
@Test
- @Ignore("b/120845532")
public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
@@ -301,8 +299,7 @@ public class HdmiCecLocalDevicePlaybackTest {
}
@Test
- @Ignore("b/120845532")
- public void handleSystemAudioModeStatusOn_DirectltToLocalDeviceFromAudioSystem() {
+ public void handleSystemAudioModeStatusOn_DirectlyToLocalDeviceFromAudioSystem() {
mHdmiControlService.setSystemAudioActivated(false);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
HdmiCecMessage message =
@@ -617,4 +614,19 @@ public class HdmiCecLocalDevicePlaybackTest {
assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
}
+
+ @Test
+ public void handleSetStreamPath_afterHotplug_hasCorrectActiveSource() {
+ mHdmiControlService.onHotplug(1, false);
+ mHdmiControlService.onHotplug(1, true);
+
+ HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
+ mPlaybackPhysicalAddress);
+ mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+ mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress());
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/job/JobSetTest.java b/services/tests/servicestests/src/com/android/server/job/JobSetTest.java
index 6b7634db8a60..62cc111e4dae 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobSetTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobSetTest.java
@@ -97,9 +97,9 @@ public class JobSetTest {
mJobSet.remove(testJob1);
mJobSet.remove(testJob2);
assertHaveSameJobs(mJobSet.mJobsPerSourceUid, mJobSet.mJobs);
- mJobSet.removeJobsOfNonUsers(new int[] {mContext.getUserId(), SECONDARY_USER_ID_1});
+ mJobSet.removeJobsOfUnlistedUsers(new int[] {mContext.getUserId(), SECONDARY_USER_ID_1});
assertHaveSameJobs(mJobSet.mJobsPerSourceUid, mJobSet.mJobs);
- mJobSet.removeJobsOfNonUsers(new int[] {mContext.getUserId()});
+ mJobSet.removeJobsOfUnlistedUsers(new int[] {mContext.getUserId()});
assertTrue("mJobs should be empty", mJobSet.mJobs.size() == 0);
assertTrue("mJobsPerSourceUid should be empty", mJobSet.mJobsPerSourceUid.size() == 0);
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
index e08eea298aaf..08392737350a 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
@@ -160,7 +160,7 @@ class OverlayActorEnforcerTests {
private val hasPermission: Boolean = false,
private val overlayableInfo: OverlayableInfo? = null,
private vararg val packageNames: String = arrayOf("com.test.actor.one")
- ) : OverlayableInfoCallback {
+ ) : PackageManagerHelper {
override fun getNamedActors() = if (isActor) {
mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
@@ -195,6 +195,14 @@ class OverlayActorEnforcerTests {
}
}
+ override fun getConfigSignaturePackage(): String {
+ throw UnsupportedOperationException()
+ }
+
+ override fun getOverlayPackages(userId: Int): MutableList<PackageInfo> {
+ throw UnsupportedOperationException()
+ }
+
override fun signaturesMatching(pkgName1: String, pkgName2: String, userId: Int): Boolean {
throw UnsupportedOperationException()
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java
index b7692f912e39..e281f2b206f5 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java
@@ -44,9 +44,9 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI
@Test
public void testUpdateOverlaysForUser() {
final OverlayManagerServiceImpl impl = getImpl();
- addSystemPackage(target(TARGET), USER);
- addSystemPackage(target("some.other.target"), USER);;
- addSystemPackage(overlay(OVERLAY, TARGET), USER);
+ addPackage(target(TARGET), USER);
+ addPackage(target("some.other.target"), USER);
+ addPackage(overlay(OVERLAY, TARGET), USER);
// do nothing, expect no change
final List<String> a = impl.updateOverlaysForUser(USER);
@@ -54,7 +54,7 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI
assertTrue(a.contains(TARGET));
// upgrade overlay, keep target
- addSystemPackage(overlay(OVERLAY, TARGET), USER);
+ addPackage(overlay(OVERLAY, TARGET), USER);
final List<String> b = impl.updateOverlaysForUser(USER);
assertEquals(1, b.size());
@@ -66,7 +66,7 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI
assertTrue(c.contains(TARGET));
// upgrade overlay, switch to new target
- addSystemPackage(overlay(OVERLAY, "some.other.target"), USER);
+ addPackage(overlay(OVERLAY, "some.other.target"), USER);
final List<String> d = impl.updateOverlaysForUser(USER);
assertEquals(2, d.size());
assertTrue(d.containsAll(Arrays.asList(TARGET, "some.other.target")));
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
index f4c5506c7001..c1d862ab2ad4 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
@@ -19,6 +19,7 @@ package com.android.server.om;
import static android.content.om.OverlayInfo.STATE_DISABLED;
import static android.content.om.OverlayInfo.STATE_ENABLED;
import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
+import static android.os.OverlayablePolicy.CONFIG_SIGNATURE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -49,6 +50,10 @@ public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTes
private static final String OVERLAY3 = OVERLAY + "3";
private static final int USER3 = USER2 + 1;
+ private static final String CONFIG_SIGNATURE_REFERENCE_PKG = "com.dummy.ref";
+ private static final String CERT_CONFIG_OK = "config_certificate_ok";
+ private static final String CERT_CONFIG_NOK = "config_certificate_nok";
+
@Test
public void testGetOverlayInfo() {
installNewPackage(overlay(OVERLAY, TARGET), USER);
@@ -204,4 +209,87 @@ public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTes
impl.setEnabled(OVERLAY, true, USER);
assertEquals(0, listener.count);
}
+
+ @Test
+ public void testConfigSignaturePolicyOk() {
+ setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
+ reinitializeImpl();
+
+ addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+ installNewPackage(target(TARGET), USER);
+ installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_OK), USER);
+
+ final DummyIdmapDaemon idmapd = getIdmapd();
+ final DummyDeviceState state = getState();
+ String overlayPath = state.select(OVERLAY, USER).apkPath;
+ assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+ DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+ assertTrue((CONFIG_SIGNATURE & idmap.policies) == CONFIG_SIGNATURE);
+ }
+
+ @Test
+ public void testConfigSignaturePolicyCertNok() {
+ setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
+ reinitializeImpl();
+
+ addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+ installNewPackage(target(TARGET), USER);
+ installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+ final DummyIdmapDaemon idmapd = getIdmapd();
+ final DummyDeviceState state = getState();
+ String overlayPath = state.select(OVERLAY, USER).apkPath;
+ assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+ DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+ assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+ }
+
+ @Test
+ public void testConfigSignaturePolicyNoConfig() {
+ addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+ installNewPackage(target(TARGET), USER);
+ installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+ final DummyIdmapDaemon idmapd = getIdmapd();
+ final DummyDeviceState state = getState();
+ String overlayPath = state.select(OVERLAY, USER).apkPath;
+ assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+ DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+ assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+ }
+
+ @Test
+ public void testConfigSignaturePolicyNoRefPkg() {
+ installNewPackage(target(TARGET), USER);
+ installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+ final DummyIdmapDaemon idmapd = getIdmapd();
+ final DummyDeviceState state = getState();
+ String overlayPath = state.select(OVERLAY, USER).apkPath;
+ assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+ DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+ assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+ }
+
+ @Test
+ public void testConfigSignaturePolicyRefPkgNotSystem() {
+ setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
+ reinitializeImpl();
+
+ addPackage(app(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+ installNewPackage(target(TARGET), USER);
+ installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+ final DummyIdmapDaemon idmapd = getIdmapd();
+ final DummyDeviceState state = getState();
+ String overlayPath = state.select(OVERLAY, USER).apkPath;
+ assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+ DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+ assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
index 733310b2508a..2faf29f45375 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
@@ -27,6 +27,7 @@ import android.content.om.OverlayInfo.State;
import android.content.om.OverlayableInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -52,6 +53,7 @@ class OverlayManagerServiceImplTestsBase {
private DummyPackageManagerHelper mPackageManager;
private DummyIdmapDaemon mIdmapDaemon;
private OverlayConfig mOverlayConfig;
+ private String mConfigSignaturePackageName;
@Before
public void setUp() {
@@ -83,6 +85,18 @@ class OverlayManagerServiceImplTestsBase {
return mListener;
}
+ DummyIdmapDaemon getIdmapd() {
+ return mIdmapDaemon;
+ }
+
+ DummyDeviceState getState() {
+ return mState;
+ }
+
+ void setConfigSignaturePackageName(String packageName) {
+ mConfigSignaturePackageName = packageName;
+ }
+
void assertState(@State int expected, final String overlayPackageName, int userId) {
final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
if (info == null) {
@@ -102,9 +116,14 @@ class OverlayManagerServiceImplTestsBase {
assertEquals(expected, actual);
}
+ DummyDeviceState.PackageBuilder app(String packageName) {
+ return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
+ null /* targetOverlayableName */, "data");
+ }
+
DummyDeviceState.PackageBuilder target(String packageName) {
return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
- null /* targetOverlayableName */);
+ null /* targetOverlayableName */, "");
}
DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName) {
@@ -114,10 +133,10 @@ class OverlayManagerServiceImplTestsBase {
DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName,
String targetOverlayableName) {
return new DummyDeviceState.PackageBuilder(packageName, targetPackageName,
- targetOverlayableName);
+ targetOverlayableName, "");
}
- void addSystemPackage(DummyDeviceState.PackageBuilder pkg, int userId) {
+ void addPackage(DummyDeviceState.PackageBuilder pkg, int userId) {
mState.add(pkg, userId);
}
@@ -242,15 +261,17 @@ class OverlayManagerServiceImplTestsBase {
private String packageName;
private String targetPackage;
private String certificate = "[default]";
+ private String partition;
private int version = 0;
private ArrayList<String> overlayableNames = new ArrayList<>();
private String targetOverlayableName;
private PackageBuilder(String packageName, String targetPackage,
- String targetOverlayableName) {
+ String targetOverlayableName, String partition) {
this.packageName = packageName;
this.targetPackage = targetPackage;
this.targetOverlayableName = targetOverlayableName;
+ this.partition = partition;
}
PackageBuilder setCertificate(String certificate) {
@@ -269,9 +290,19 @@ class OverlayManagerServiceImplTestsBase {
}
Package build() {
- final String apkPath = String.format("%s/%s/base.apk",
- targetPackage == null ? "/system/app/:" : "/vendor/overlay/:",
- packageName);
+ String path = "";
+ if (TextUtils.isEmpty(partition)) {
+ if (targetPackage == null) {
+ path = "/system/app";
+ } else {
+ path = "/vendor/overlay";
+ }
+ } else {
+ String type = targetPackage == null ? "app" : "overlay";
+ path = String.format("%s/%s", partition, type);
+ }
+
+ final String apkPath = String.format("%s/%s/base.apk", path, packageName);
final Package newPackage = new Package(packageName, targetPackage,
targetOverlayableName, version, apkPath, certificate);
newPackage.overlayableNames.addAll(overlayableNames);
@@ -302,8 +333,7 @@ class OverlayManagerServiceImplTestsBase {
}
}
- static final class DummyPackageManagerHelper implements PackageManagerHelper,
- OverlayableInfoCallback {
+ final class DummyPackageManagerHelper implements PackageManagerHelper {
private final DummyDeviceState mState;
private DummyPackageManagerHelper(DummyDeviceState state) {
@@ -343,6 +373,11 @@ class OverlayManagerServiceImplTestsBase {
.collect(Collectors.toList());
}
+ @Override
+ public @NonNull String getConfigSignaturePackage() {
+ return mConfigSignaturePackageName;
+ }
+
@Nullable
@Override
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt
index 78c708084d38..d888b9258d33 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayReferenceMapperTests.kt
@@ -25,7 +25,6 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import org.testng.Assert.assertThrows
@RunWith(Parameterized::class)
class OverlayReferenceMapperTests {
@@ -160,9 +159,6 @@ class OverlayReferenceMapperTests {
expected.forEach { (actorPkgName, expectedPkgNames) ->
expectedPkgNames.forEach { expectedPkgName ->
if (deferRebuild) {
- assertThrows(IllegalStateException::class.java) {
- mapper.isValidActor(expectedPkgName, actorPkgName)
- }
mapper.rebuildIfDeferred()
deferRebuild = false
}
@@ -187,7 +183,7 @@ class OverlayReferenceMapperTests {
)
)
) = OverlayReferenceMapper(deferRebuild, object : OverlayReferenceMapper.Provider {
- override fun getActorPkg(actor: String?) =
+ override fun getActorPkg(actor: String) =
OverlayActorEnforcer.getPackageNameForActor(actor, namedActors).first
override fun getTargetToOverlayables(pkg: AndroidPackage) =
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 2d9c6ce40a40..f991dff2797f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -19,7 +19,6 @@ package com.android.server.pm;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -70,8 +69,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.function.IntFunction;
-import java.util.stream.Collectors;
@Presubmit
@RunWith(JUnit4.class)
@@ -805,24 +802,24 @@ public class AppsFilterTest {
queriesProviderAppId);
final SparseArray<int[]> systemFilter =
- appsFilter.getVisibilityWhitelist(system, USER_ARRAY, mExisting);
+ appsFilter.getVisibilityAllowList(system, USER_ARRAY, mExisting);
assertThat(toList(systemFilter.get(SYSTEM_USER)),
contains(seesNothingAppId, hasProviderAppId, queriesProviderAppId));
final SparseArray<int[]> seesNothingFilter =
- appsFilter.getVisibilityWhitelist(seesNothing, USER_ARRAY, mExisting);
+ appsFilter.getVisibilityAllowList(seesNothing, USER_ARRAY, mExisting);
assertThat(toList(seesNothingFilter.get(SYSTEM_USER)),
contains(seesNothingAppId));
assertThat(toList(seesNothingFilter.get(SECONDARY_USER)),
contains(seesNothingAppId));
final SparseArray<int[]> hasProviderFilter =
- appsFilter.getVisibilityWhitelist(hasProvider, USER_ARRAY, mExisting);
+ appsFilter.getVisibilityAllowList(hasProvider, USER_ARRAY, mExisting);
assertThat(toList(hasProviderFilter.get(SYSTEM_USER)),
contains(hasProviderAppId, queriesProviderAppId));
SparseArray<int[]> queriesProviderFilter =
- appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
+ appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
contains(queriesProviderAppId));
@@ -831,7 +828,7 @@ public class AppsFilterTest {
// ensure implicit access is included in the filter
queriesProviderFilter =
- appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
+ appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
contains(hasProviderAppId, queriesProviderAppId));
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index fa9ee19cba9d..aa92ba49d190 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -57,6 +57,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.server.LocalServices;
import com.android.server.pm.permission.PermissionSettings;
@@ -86,6 +87,8 @@ public class PackageManagerSettingsTests {
@Mock
PermissionSettings mPermissionSettings;
+ @Mock
+ RuntimePermissionsPersistence mRuntimePermissionsPersistence;
@Before
public void initializeMocks() {
@@ -106,7 +109,8 @@ public class PackageManagerSettingsTests {
writeOldFiles();
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ Settings settings = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
assertThat(settings.readLPw(createFakeUsers()), is(true));
verifyKeySetMetaData(settings);
}
@@ -119,7 +123,8 @@ public class PackageManagerSettingsTests {
writeOldFiles();
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ Settings settings = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
assertThat(settings.readLPw(createFakeUsers()), is(true));
// write out, read back in and verify the same
@@ -134,7 +139,8 @@ public class PackageManagerSettingsTests {
writeOldFiles();
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ Settings settings = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
assertThat(settings.readLPw(createFakeUsers()), is(true));
assertThat(settings.getPackageLPr(PACKAGE_NAME_3), is(notNullValue()));
assertThat(settings.getPackageLPr(PACKAGE_NAME_1), is(notNullValue()));
@@ -155,12 +161,14 @@ public class PackageManagerSettingsTests {
writeOldFiles();
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ Settings settings = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
assertThat(settings.readLPw(createFakeUsers()), is(true));
settings.writeLPr();
// Create Settings again to make it read from the new files
- settings = new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ settings = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
assertThat(settings.readLPw(createFakeUsers()), is(true));
PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_2);
@@ -183,7 +191,7 @@ public class PackageManagerSettingsTests {
writePackageRestrictions_noSuspendingPackageXml(0);
final Object lock = new Object();
final Context context = InstrumentationRegistry.getTargetContext();
- final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, lock);
+ final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, lock);
settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, createPackageSetting(PACKAGE_NAME_2));
settingsUnderTest.readPackageRestrictionsLPr(0);
@@ -206,7 +214,7 @@ public class PackageManagerSettingsTests {
writePackageRestrictions_noSuspendParamsMapXml(0);
final Object lock = new Object();
final Context context = InstrumentationRegistry.getTargetContext();
- final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, lock);
+ final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null, lock);
settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
settingsUnderTest.readPackageRestrictionsLPr(0);
@@ -233,7 +241,8 @@ public class PackageManagerSettingsTests {
@Test
public void testReadWritePackageRestrictions_suspendInfo() {
final Context context = InstrumentationRegistry.getTargetContext();
- final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, new Object());
+ final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null,
+ new Object());
final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1);
final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2);
final PackageSetting ps3 = createPackageSetting(PACKAGE_NAME_3);
@@ -330,7 +339,8 @@ public class PackageManagerSettingsTests {
@Test
public void testReadWritePackageRestrictions_distractionFlags() {
final Context context = InstrumentationRegistry.getTargetContext();
- final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, new Object());
+ final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, null,
+ new Object());
final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1);
final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2);
final PackageSetting ps3 = createPackageSetting(PACKAGE_NAME_3);
@@ -381,7 +391,8 @@ public class PackageManagerSettingsTests {
writeOldFiles();
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- Settings settings = new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ Settings settings = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
assertThat(settings.readLPw(createFakeUsers()), is(true));
// Enable/Disable a package
@@ -558,8 +569,8 @@ public class PackageManagerSettingsTests {
public void testUpdatePackageSetting03() {
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- final Settings testSettings01 =
- new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ final Settings testSettings01 = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
final SharedUserSetting testUserSetting01 = createSharedUserSetting(
testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/);
final PackageSetting testPkgSetting01 =
@@ -673,8 +684,8 @@ public class PackageManagerSettingsTests {
public void testCreateNewSetting03() {
final Context context = InstrumentationRegistry.getContext();
final Object lock = new Object();
- final Settings testSettings01 =
- new Settings(context.getFilesDir(), mPermissionSettings, lock);
+ final Settings testSettings01 = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
final SharedUserSetting testUserSetting01 = createSharedUserSetting(
testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/);
final PackageSetting testPkgSetting01 = Settings.createNewSetting(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 10976882048a..980772bb08bc 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -166,6 +166,7 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
@@ -178,7 +179,6 @@ import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -3774,6 +3774,27 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testEnqueuedAdjustmentAppliesAdjustments_MultiNotifications() throws Exception {
+ final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel);
+ final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel);
+ mService.addEnqueuedNotification(r1);
+ mService.addEnqueuedNotification(r2);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_IMPORTANCE,
+ IMPORTANCE_HIGH);
+ Adjustment adjustment = new Adjustment(
+ r1.getSbn().getPackageName(), r1.getKey(), signals,
+ "", r1.getUser().getIdentifier());
+
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+ assertEquals(IMPORTANCE_HIGH, r1.getImportance());
+ assertEquals(IMPORTANCE_HIGH, r2.getImportance());
+ }
+
+ @Test
public void testRestore() throws Exception {
int systemChecks = mService.countSystemChecks;
mBinderService.applyRestore(null, USER_SYSTEM);
@@ -6434,7 +6455,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testOnUnlockUser() {
UserInfo ui = new UserInfo();
ui.id = 10;
- mService.onUnlockUser(ui);
+ mService.onUserUnlocking(new TargetUser(ui));
waitForIdle();
verify(mHistoryManager, timeout(MAX_POST_DELAY).times(1)).onUserUnlocked(ui.id);
@@ -6444,7 +6465,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testOnStopUser() {
UserInfo ui = new UserInfo();
ui.id = 10;
- mService.onStopUser(ui);
+ mService.onUserStopping(new TargetUser(ui));
waitForIdle();
verify(mHistoryManager, timeout(MAX_POST_DELAY).times(1)).onUserStopped(ui.id);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index f69d7c332382..1eb45d587d33 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -59,7 +59,7 @@ import org.junit.runner.RunWith;
@Presubmit
@RunWith(WindowTestRunner.class)
// TODO(b/144248496): Merge to DisplayContentTests
-public class ActivityDisplayTests extends ActivityTestsBase {
+public class ActivityDisplayTests extends WindowTestsBase {
@Test
public void testLastFocusedStackIsUpdatedWhenMovingStack() {
@@ -89,9 +89,9 @@ public class ActivityDisplayTests extends ActivityTestsBase {
// Create a pinned stack and move to front.
final Task pinnedStack = mRootWindowContainer.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task pinnedTask = new TaskBuilder(mService.mStackSupervisor)
+ final Task pinnedTask = new TaskBuilder(mAtm.mStackSupervisor)
.setStack(pinnedStack).build();
- new ActivityBuilder(mService).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
+ new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
.setTask(pinnedTask).build();
pinnedStack.moveToFront("movePinnedStackToFront");
@@ -140,7 +140,7 @@ public class ActivityDisplayTests extends ActivityTestsBase {
// Create a display which supports system decoration and allows reparenting stacks to
// another display when the display is removed.
final DisplayContent display = new TestDisplayContent.Builder(
- mService, 1000, 1500).setSystemDecorations(true).build();
+ mAtm, 1000, 1500).setSystemDecorations(true).build();
doReturn(false).when(display).shouldDestroyContentOnRemove();
// Put home stack on the display.
@@ -162,9 +162,9 @@ public class ActivityDisplayTests extends ActivityTestsBase {
private Task createFullscreenStackWithSimpleActivityAt(DisplayContent display) {
final Task fullscreenStack = display.getDefaultTaskDisplayArea().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task fullscreenTask = new TaskBuilder(mService.mStackSupervisor)
+ final Task fullscreenTask = new TaskBuilder(mAtm.mStackSupervisor)
.setStack(fullscreenStack).build();
- new ActivityBuilder(mService).setTask(fullscreenTask).build();
+ new ActivityBuilder(mAtm).setTask(fullscreenTask).build();
return fullscreenStack;
}
@@ -197,7 +197,7 @@ public class ActivityDisplayTests extends ActivityTestsBase {
assertNull(display.topRunningActivity(true /* considerKeyguardState */));
// Add activity that should be shown on the keyguard.
- final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
+ final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setStack(stack)
.setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
@@ -226,7 +226,7 @@ public class ActivityDisplayTests extends ActivityTestsBase {
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task alwaysOnTopStack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(alwaysOnTopStack).build();
alwaysOnTopStack.setAlwaysOnTop(true);
taskDisplayArea.positionChildAt(POSITION_TOP, alwaysOnTopStack,
@@ -322,10 +322,10 @@ public class ActivityDisplayTests extends ActivityTestsBase {
ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task stack4 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task task1 = new TaskBuilder(mService.mStackSupervisor).setStack(stack1).build();
- final Task task2 = new TaskBuilder(mService.mStackSupervisor).setStack(stack2).build();
- final Task task3 = new TaskBuilder(mService.mStackSupervisor).setStack(stack3).build();
- final Task task4 = new TaskBuilder(mService.mStackSupervisor).setStack(stack4).build();
+ final Task task1 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack1).build();
+ final Task task2 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack2).build();
+ final Task task3 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack3).build();
+ final Task task4 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack4).build();
// Reordering stacks while removing stacks.
doAnswer(invocation -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index feac6dbe1051..46c3e22da38c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -59,7 +59,7 @@ import java.util.concurrent.TimeUnit;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
+public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
private ActivityMetricsLogger mActivityMetricsLogger;
private ActivityMetricsLogger.LaunchingState mLaunchingState;
private ActivityMetricsLaunchObserver mLaunchObserver;
@@ -81,11 +81,11 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
// Sometimes we need an ActivityRecord for ActivityMetricsLogger to do anything useful.
// This seems to be the easiest way to create an ActivityRecord.
- mTrampolineActivity = new ActivityBuilder(mService)
+ mTrampolineActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setComponent(createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, "TrampolineActivity"))
.build();
- mTopActivity = new ActivityBuilder(mService)
+ mTopActivity = new ActivityBuilder(mAtm)
.setTask(mTrampolineActivity.getTask())
.setComponent(createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, "TopActivity"))
.build();
@@ -121,7 +121,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
private <T> T verifyAsync(T mock) {
// With WindowTestRunner, all test methods are inside WM lock, so we have to unblock any
// messages that are waiting for the lock.
- waitHandlerIdle(mService.mH);
+ waitHandlerIdle(mAtm.mH);
// AMLO callbacks happen on a separate thread than AML calls, so we need to use a timeout.
return verify(mock, timeout(TimeUnit.SECONDS.toMillis(5)));
}
@@ -192,7 +192,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
// Suppress resume when creating the record because we want to notify logger manually.
mSupervisor.beginDeferResume();
// Create an activity with different process that meets process switch.
- final ActivityRecord noDrawnActivity = new ActivityBuilder(mService)
+ final ActivityRecord noDrawnActivity = new ActivityBuilder(mAtm)
.setTask(mTopActivity.getTask())
.setProcessName("other")
.build();
@@ -321,7 +321,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
onActivityLaunched(mTopActivity);
final ActivityMetricsLogger.LaunchingState previousState = mLaunchingState;
- final ActivityRecord otherActivity = new ActivityBuilder(mService)
+ final ActivityRecord otherActivity = new ActivityBuilder(mAtm)
.setComponent(createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, "OtherActivity"))
.setCreateTask(true)
.build();
@@ -345,7 +345,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
.setDisplay(addNewDisplayContentAt(DisplayContent.POSITION_BOTTOM))
.setCreateActivity(false)
.build();
- final ActivityRecord activityOnNewDisplay = new ActivityBuilder(mService)
+ final ActivityRecord activityOnNewDisplay = new ActivityBuilder(mAtm)
.setStack(stack)
.setCreateTask(true)
.setProcessName("new")
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index e45ced64c5b6..e3830f686a42 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -67,7 +67,6 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -122,7 +121,7 @@ import org.mockito.invocation.InvocationOnMock;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivityRecordTests extends ActivityTestsBase {
+public class ActivityRecordTests extends WindowTestsBase {
private Task mStack;
private Task mTask;
private ActivityRecord mActivity;
@@ -133,7 +132,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
mTask = mStack.getBottomMostTask();
mActivity = mTask.getTopNonFinishingActivity();
- setBooted(mService);
+ setBooted(mAtm);
}
@Test
@@ -152,16 +151,16 @@ public class ActivityRecordTests extends ActivityTestsBase {
public void testStackCleanupOnTaskRemoval() {
mStack.removeChild(mTask, null /*reason*/);
// Stack should be gone on task removal.
- assertNull(mService.mRootWindowContainer.getStack(mStack.mTaskId));
+ assertNull(mAtm.mRootWindowContainer.getStack(mStack.mTaskId));
}
@Test
public void testRemoveChildWithOverlayActivity() {
final ActivityRecord overlayActivity =
- new ActivityBuilder(mService).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setTask(mTask).build();
overlayActivity.setTaskOverlay(true);
final ActivityRecord overlayActivity2 =
- new ActivityBuilder(mService).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setTask(mTask).build();
overlayActivity2.setTaskOverlay(true);
mTask.removeChild(overlayActivity2, "test");
@@ -170,7 +169,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testNoCleanupMovingActivityInSameStack() {
- final Task newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+ final Task newTask = new TaskBuilder(mAtm.mStackSupervisor).setStack(mStack).build();
mActivity.reparent(newTask, 0, null /*reason*/);
verify(mStack, times(0)).cleanUpActivityReferences(any());
}
@@ -213,7 +212,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
// Make sure the state does not change if we are not the current top activity.
mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind");
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
mStack.mTranslucentActivityWaiting = topActivity;
mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
assertTrue(mActivity.isState(STARTED));
@@ -231,8 +230,8 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testCanBeLaunchedOnDisplay() {
- mService.mSupportsMultiWindow = true;
- final ActivityRecord activity = new ActivityBuilder(mService).build();
+ mAtm.mSupportsMultiWindow = true;
+ final ActivityRecord activity = new ActivityBuilder(mAtm).build();
// An activity can be launched on default display.
assertTrue(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY));
@@ -251,7 +250,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
// Set options for two ActivityRecords in same Task. Apply one ActivityRecord options.
// Pending options should be cleared for both ActivityRecords
- ActivityRecord activity2 = new ActivityBuilder(mService).setTask(mTask).build();
+ ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(mTask).build();
activity2.updateOptionsLocked(activityOptions);
mActivity.updateOptionsLocked(activityOptions);
mActivity.applyOptionsLocked();
@@ -260,8 +259,8 @@ public class ActivityRecordTests extends ActivityTestsBase {
// Set options for two ActivityRecords in separate Tasks. Apply one ActivityRecord options.
// Pending options should be cleared for only ActivityRecord that was applied
- Task task2 = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
- activity2 = new ActivityBuilder(mService).setTask(task2).build();
+ Task task2 = new TaskBuilder(mAtm.mStackSupervisor).setStack(mStack).build();
+ activity2 = new ActivityBuilder(mAtm).setTask(task2).build();
activity2.updateOptionsLocked(activityOptions);
mActivity.updateOptionsLocked(activityOptions);
mActivity.applyOptionsLocked();
@@ -362,7 +361,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testSetRequestedOrientationUpdatesConfiguration() throws Exception {
- mActivity = new ActivityBuilder(mService)
+ mActivity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT)
.build();
@@ -405,7 +404,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
final ActivityConfigurationChangeItem expected =
ActivityConfigurationChangeItem.obtain(newConfig);
- verify(mService.getLifecycleManager()).scheduleTransaction(eq(mActivity.app.getThread()),
+ verify(mAtm.getLifecycleManager()).scheduleTransaction(eq(mActivity.app.getThread()),
eq(mActivity.appToken), eq(expected));
}
@@ -500,9 +499,9 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testShouldMakeActive_nonTopVisible() {
- ActivityRecord finishingActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ ActivityRecord finishingActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
finishingActivity.finishing = true;
- ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
mActivity.setState(Task.ActivityState.STOPPED, "Testing");
assertEquals(false, mActivity.shouldMakeActive(null /* activeActivity */));
@@ -528,7 +527,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
mActivity.setState(Task.ActivityState.STOPPED, "Testing");
spyOn(mStack);
- ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
mActivity.addResultLocked(topActivity, "resultWho", 0, 0, new Intent());
topActivity.finishing = true;
@@ -539,7 +538,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testPushConfigurationWhenLaunchTaskBehind() throws Exception {
- mActivity = new ActivityBuilder(mService)
+ mActivity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setLaunchTaskBehind(true)
.setConfigChanges(CONFIG_ORIENTATION)
@@ -574,7 +573,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
final ActivityConfigurationChangeItem expected =
ActivityConfigurationChangeItem.obtain(newConfig);
- verify(mService.getLifecycleManager()).scheduleTransaction(
+ verify(mAtm.getLifecycleManager()).scheduleTransaction(
eq(mActivity.app.getThread()), eq(mActivity.appToken), eq(expected));
} finally {
stack.getDisplayArea().removeChild(stack);
@@ -583,7 +582,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testShouldStartWhenMakeClientActive() {
- ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.setOccludesParent(false);
mActivity.setState(Task.ActivityState.STOPPED, "Testing");
mActivity.setVisibility(true);
@@ -621,7 +620,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
public void testCanLaunchHomeActivityFromChooser() {
ComponentName chooserComponent = ComponentName.unflattenFromString(
Resources.getSystem().getString(R.string.config_chooserActivity));
- ActivityRecord chooserActivity = new ActivityBuilder(mService).setComponent(
+ ActivityRecord chooserActivity = new ActivityBuilder(mAtm).setComponent(
chooserComponent).build();
assertThat(mActivity.canLaunchHomeActivity(NOBODY_UID, chooserActivity)).isTrue();
}
@@ -736,7 +735,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
// Put a visible activity on top, so the finishing activity doesn't have to wait until the
// next activity reports idle to destroy it.
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = true;
topActivity.nowVisible = true;
topActivity.setState(RESUMED, "test");
@@ -914,7 +913,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
public void testFinishActivityIfPossible_nonVisibleNoAppTransition() {
// Put an activity on top of test activity to make it invisible and prevent us from
// accidentally resuming the topmost one again.
- new ActivityBuilder(mService).build();
+ new ActivityBuilder(mAtm).build();
mActivity.mVisibleRequested = false;
mActivity.setState(STOPPED, "test");
@@ -992,7 +991,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
*/
@Test
public void testCompleteFinishing_waitForNextVisible() {
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = true;
topActivity.nowVisible = true;
topActivity.finishing = true;
@@ -1017,7 +1016,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
*/
@Test
public void testCompleteFinishing_noWaitForNextVisible_alreadyInvisible() {
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = false;
topActivity.nowVisible = false;
topActivity.finishing = true;
@@ -1039,7 +1038,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
*/
@Test
public void testCompleteFinishing_waitForIdle() {
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = true;
topActivity.nowVisible = true;
topActivity.finishing = true;
@@ -1060,7 +1059,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
*/
@Test
public void testCompleteFinishing_noWaitForNextVisible_stopped() {
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = false;
topActivity.nowVisible = false;
topActivity.finishing = true;
@@ -1081,7 +1080,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
*/
@Test
public void testCompleteFinishing_noWaitForNextVisible_nonFocusedStack() {
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = true;
topActivity.nowVisible = true;
topActivity.finishing = true;
@@ -1114,7 +1113,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
// Make keyguard locked and set the top activity show-when-locked.
KeyguardController keyguardController = mActivity.mStackSupervisor.getKeyguardController();
doReturn(true).when(keyguardController).isKeyguardLocked();
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.mVisibleRequested = true;
topActivity.nowVisible = true;
topActivity.setState(RESUMED, "true");
@@ -1143,18 +1142,18 @@ public class ActivityRecordTests extends ActivityTestsBase {
*/
@Test
public void testCompleteFinishing_ensureActivitiesVisible() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
firstActivity.mVisibleRequested = false;
firstActivity.nowVisible = false;
firstActivity.setState(STOPPED, "true");
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
secondActivity.mVisibleRequested = true;
secondActivity.nowVisible = true;
secondActivity.setState(PAUSED, "true");
final ActivityRecord translucentActivity =
- new ActivityBuilder(mService).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setTask(mTask).build();
translucentActivity.mVisibleRequested = true;
translucentActivity.nowVisible = true;
translucentActivity.setState(RESUMED, "true");
@@ -1327,12 +1326,15 @@ public class ActivityRecordTests extends ActivityTestsBase {
public void testRemoveFromHistory() {
final Task stack = mActivity.getRootTask();
final Task task = mActivity.getTask();
+ final WindowProcessController wpc = mActivity.app;
+ assertTrue(wpc.hasActivities());
mActivity.removeFromHistory("test");
assertEquals(DESTROYED, mActivity.getState());
assertNull(mActivity.app);
assertNull(mActivity.getTask());
+ assertFalse(wpc.hasActivities());
assertEquals(0, task.getChildCount());
assertEquals(task.getRootTask(), task);
assertEquals(0, stack.getChildCount());
@@ -1393,7 +1395,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
final Task firstTaskRecord = mActivity.getTask();
final ActivityRecord secondActivityRecord =
- new ActivityBuilder(mService).setTask(firstTaskRecord).setUseProcess(wpc).build();
+ new ActivityBuilder(mAtm).setTask(firstTaskRecord).setUseProcess(wpc).build();
assertTrue(wpc.registeredForActivityConfigChanges());
assertEquals(0, secondActivityRecord.getMergedOverrideConfiguration()
@@ -1406,7 +1408,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
assertTrue(wpc.registeredForActivityConfigChanges());
final ActivityRecord secondActivityRecord =
- new ActivityBuilder(mService).setTask(mTask).setUseProcess(wpc).build();
+ new ActivityBuilder(mAtm).setTask(mTask).setUseProcess(wpc).build();
assertTrue(wpc.registeredForActivityConfigChanges());
assertEquals(0, secondActivityRecord.getMergedOverrideConfiguration()
@@ -1502,7 +1504,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
params.width = params.height = WindowManager.LayoutParams.MATCH_PARENT;
final WindowTestUtils.TestWindowState w = new WindowTestUtils.TestWindowState(
- mService.mWindowManager, mock(Session.class), new TestIWindow(), params, mActivity);
+ mAtm.mWindowManager, mock(Session.class), new TestIWindow(), params, mActivity);
mActivity.addWindow(w);
// Assume the activity is launching in different rotation, and there was an available
@@ -1523,7 +1525,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
any() /* outContentInsets */, any() /* outStableInsets */,
any() /* outDisplayCutout */, any() /* outInputChannel */,
any() /* outInsetsState */, any() /* outActiveControls */);
- TaskSnapshotSurface.create(mService.mWindowManager, mActivity, snapshot);
+ TaskSnapshotSurface.create(mAtm.mWindowManager, mActivity, snapshot);
} catch (RemoteException ignored) {
} finally {
reset(session);
@@ -1599,7 +1601,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
final Configuration initialConf =
new Configuration(mActivity.getMergedOverrideConfiguration());
final Task initialTask = mActivity.getTask();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(initialTask)
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(initialTask)
.setUseProcess(wpc).build();
assertTrue(wpc.registeredForActivityConfigChanges());
@@ -1693,12 +1695,12 @@ public class ActivityRecordTests extends ActivityTestsBase {
if (defaultDisplay) {
display = mRootWindowContainer.getDefaultDisplay();
} else {
- display = new TestDisplayContent.Builder(mService, 2000, 1000).setDensityDpi(300)
+ display = new TestDisplayContent.Builder(mAtm, 2000, 1000).setDensityDpi(300)
.setPosition(DisplayContent.POSITION_TOP).build();
}
final Task stack = display.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
- return new ActivityBuilder(mService).setTask(task).setUseProcess(process).build();
+ return new ActivityBuilder(mAtm).setTask(task).setUseProcess(process).build();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 197c89a2d479..addf1ffe40c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -55,7 +55,7 @@ import org.junit.runner.RunWith;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivityStackSupervisorTests extends ActivityTestsBase {
+public class ActivityStackSupervisorTests extends WindowTestsBase {
private Task mFullscreenStack;
@Before
@@ -69,7 +69,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
*/
@Test
public void testStoppingActivityRemovedWhenResumed() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(mFullscreenStack).build();
mSupervisor.mStoppingActivities.add(firstActivity);
@@ -83,7 +83,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
*/
@Test
public void testReportWaitingActivityLaunchedIfNeeded() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(mFullscreenStack).build();
final WaitResult taskToFrontWait = new WaitResult();
@@ -121,7 +121,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
task.setResizeMode(unresizableActivity.info.resizeMode);
final TaskChangeNotificationController taskChangeNotifier =
- mService.getTaskChangeNotificationController();
+ mAtm.getTaskChangeNotificationController();
spyOn(taskChangeNotifier);
mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
@@ -133,7 +133,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
reset(taskChangeNotifier);
// Put a resizable activity on top of the unresizable task.
- final ActivityRecord resizableActivity = new ActivityBuilder(mService)
+ final ActivityRecord resizableActivity = new ActivityBuilder(mAtm)
.setTask(task).build();
resizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
@@ -150,24 +150,24 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
*/
@Test
public void testNotifyTaskFocusChanged() {
- final ActivityRecord fullScreenActivityA = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord fullScreenActivityA = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(mFullscreenStack).build();
final Task taskA = fullScreenActivityA.getTask();
final TaskChangeNotificationController taskChangeNotifier =
- mService.getTaskChangeNotificationController();
+ mAtm.getTaskChangeNotificationController();
spyOn(taskChangeNotifier);
- mService.setResumedActivityUncheckLocked(fullScreenActivityA, "resumeA");
+ mAtm.setResumedActivityUncheckLocked(fullScreenActivityA, "resumeA");
verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskA.mTaskId) /* taskId */,
eq(true) /* focused */);
reset(taskChangeNotifier);
- final ActivityRecord fullScreenActivityB = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord fullScreenActivityB = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(mFullscreenStack).build();
final Task taskB = fullScreenActivityB.getTask();
- mService.setResumedActivityUncheckLocked(fullScreenActivityB, "resumeB");
+ mAtm.setResumedActivityUncheckLocked(fullScreenActivityB, "resumeB");
verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskA.mTaskId) /* taskId */,
eq(false) /* focused */);
verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskB.mTaskId) /* taskId */,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 775df74f88e0..e2948a724acd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -89,7 +89,7 @@ import java.util.function.Consumer;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivityStackTests extends ActivityTestsBase {
+public class ActivityStackTests extends WindowTestsBase {
private TaskDisplayArea mDefaultTaskDisplayArea;
private Task mStack;
private Task mTask;
@@ -105,7 +105,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testResumedActivity() {
- final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(mTask).build();
assertNull(mStack.getResumedActivity());
r.setState(RESUMED, "testResumedActivity");
assertEquals(r, mStack.getResumedActivity());
@@ -115,7 +115,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testResumedActivityFromTaskReparenting() {
- final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(mTask).build();
// Ensure moving task between two stacks updates resumed activity
r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
assertEquals(r, mStack.getResumedActivity());
@@ -133,7 +133,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testResumedActivityFromActivityReparenting() {
- final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(mTask).build();
// Ensure moving task between two stacks updates resumed activity
r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
assertEquals(r, mStack.getResumedActivity());
@@ -149,7 +149,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testPrimarySplitScreenMoveToBack() {
- TestSplitOrganizer organizer = new TestSplitOrganizer(mService);
+ TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
// We're testing an edge case here where we have primary + fullscreen rather than secondary.
organizer.setMoveToSecondaryOnEnter(false);
@@ -177,7 +177,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testMoveToPrimarySplitScreenThenMoveToBack() {
- TestSplitOrganizer organizer = new TestSplitOrganizer(mService);
+ TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
// This time, start with a fullscreen activitystack
final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
@@ -202,7 +202,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testSplitScreenMoveToBack() {
- TestSplitOrganizer organizer = new TestSplitOrganizer(mService);
+ TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
// Set up split-screen with primary on top and secondary containing the home task below
// another stack.
final Task primaryTask = mDefaultTaskDisplayArea.createStack(
@@ -241,12 +241,12 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testRemoveOrganizedTask_UpdateStackReference() {
final Task rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask();
- final ActivityRecord homeActivity = new ActivityBuilder(mService)
+ final ActivityRecord homeActivity = new ActivityBuilder(mAtm)
.setStack(rootHomeTask)
.setCreateTask(true)
.build();
final Task secondaryStack = (Task) WindowContainer.fromBinder(
- mService.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(),
+ mAtm.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(),
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder());
rootHomeTask.reparent(secondaryStack, POSITION_TOP);
@@ -292,7 +292,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testStopActivityWhenActivityDestroyed() {
- final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(mTask).build();
r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
mStack.moveToFront("testStopActivityWithDestroy");
r.stopIfPossible();
@@ -302,14 +302,14 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testFindTaskWithOverlay() {
- final ActivityRecord r = new ActivityBuilder(mService)
+ final ActivityRecord r = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setStack(mStack)
.setUid(0)
.build();
final Task task = r.getTask();
// Overlay must be for a different user to prevent recognizing a matching top activity
- final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
+ final ActivityRecord taskOverlay = new ActivityBuilder(mAtm).setTask(task)
.setUid(UserHandle.PER_USER_RANGE * 2).build();
taskOverlay.setTaskOverlay(true);
@@ -330,21 +330,21 @@ public class ActivityStackTests extends ActivityTestsBase {
targetActivity);
final ComponentName alias = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
aliasActivity);
- final Task task = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor).setStack(mStack).build();
task.origActivity = alias;
task.realActivity = target;
- new ActivityBuilder(mService).setComponent(target).setTask(task).setTargetActivity(
+ new ActivityBuilder(mAtm).setComponent(target).setTask(task).setTargetActivity(
targetActivity).build();
// Using target activity to find task.
- final ActivityRecord r1 = new ActivityBuilder(mService).setComponent(
+ final ActivityRecord r1 = new ActivityBuilder(mAtm).setComponent(
target).setTargetActivity(targetActivity).build();
RootWindowContainer.FindTaskResult result = new RootWindowContainer.FindTaskResult();
result.process(r1, mStack);
assertThat(result.mRecord).isNotNull();
// Using alias activity to find task.
- final ActivityRecord r2 = new ActivityBuilder(mService).setComponent(
+ final ActivityRecord r2 = new ActivityBuilder(mAtm).setComponent(
alias).setTargetActivity(targetActivity).build();
result = new RootWindowContainer.FindTaskResult();
result.process(r2, mStack);
@@ -377,7 +377,7 @@ public class ActivityStackTests extends ActivityTestsBase {
final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Add an activity to the pinned stack so it isn't considered empty for visibility check.
- final ActivityRecord pinnedActivity = new ActivityBuilder(mService)
+ final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setStack(pinnedStack)
.build();
@@ -676,7 +676,7 @@ public class ActivityStackTests extends ActivityTestsBase {
assertEquals(STACK_VISIBILITY_VISIBLE,
translucentStack.getVisibility(null /* starting */));
// Add an activity to the pinned stack so it isn't considered empty for visibility check.
- final ActivityRecord pinnedActivity = new ActivityBuilder(mService)
+ final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setStack(pinnedStack)
.build();
@@ -689,7 +689,7 @@ public class ActivityStackTests extends ActivityTestsBase {
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
if (topRunningHomeActivity == null) {
- topRunningHomeActivity = new ActivityBuilder(mService)
+ topRunningHomeActivity = new ActivityBuilder(mAtm)
.setStack(homeStack)
.setCreateTask(true)
.build();
@@ -721,12 +721,12 @@ public class ActivityStackTests extends ActivityTestsBase {
final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
- final ActivityRecord firstActivity = new ActivityBuilder(mService)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
.setStack(homeStack)
.setCreateTask(true)
.build();
final Task task = firstActivity.getTask();
- final ActivityRecord secondActivity = new ActivityBuilder(mService)
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
.setTask(task)
.build();
@@ -991,7 +991,6 @@ public class ActivityStackTests extends ActivityTestsBase {
TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop) {
final Task task;
if (activityType == ACTIVITY_TYPE_HOME) {
- // Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
task = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
mDefaultTaskDisplayArea.positionChildAt(onTop ? POSITION_TOP : POSITION_BOTTOM, task,
false /* includingParents */);
@@ -1009,8 +1008,8 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testFinishDisabledPackageActivities_FinishAliveActivities() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
firstActivity.setState(STOPPED, "testFinishDisabledPackageActivities");
secondActivity.setState(RESUMED, "testFinishDisabledPackageActivities");
mStack.mResumedActivity = secondActivity;
@@ -1029,10 +1028,10 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testFinishDisabledPackageActivities_RemoveNonAliveActivities() {
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(mTask).build();
// The overlay activity is not in the disabled package but it is in the same task.
- final ActivityRecord overlayActivity = new ActivityBuilder(mService).setTask(mTask)
+ final ActivityRecord overlayActivity = new ActivityBuilder(mAtm).setTask(mTask)
.setComponent(new ComponentName("package.overlay", ".OverlayActivity")).build();
// If the task only remains overlay activity, the task should also be removed.
// See {@link ActivityStack#removeFromHistory}.
@@ -1058,8 +1057,8 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testHandleAppDied() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
// Making the first activity a task overlay means it will be removed from the task's
// activities as well once second activity is removed as handleAppDied processes the
@@ -1072,7 +1071,7 @@ public class ActivityStackTests extends ActivityTestsBase {
assertEquals(2, mTask.getChildCount());
- mRootWindowContainer.handleAppDied(secondActivity.app);
+ secondActivity.app.handleAppDied();
assertFalse(mTask.hasChild());
assertFalse(mStack.hasChild());
@@ -1080,13 +1079,13 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testHandleAppDied_RelaunchesAfterCrashDuringWindowingModeResize() {
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(mTask).build();
activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
activity.launchCount = 1;
activity.setSavedState(null /* savedState */);
- mRootWindowContainer.handleAppDied(activity.app);
+ activity.app.handleAppDied();
assertEquals(1, mTask.getChildCount());
assertEquals(1, mStack.getChildCount());
@@ -1094,13 +1093,13 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringWindowingModeResize() {
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(mTask).build();
activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
activity.launchCount = 3;
activity.setSavedState(null /* savedState */);
- mRootWindowContainer.handleAppDied(activity.app);
+ activity.app.handleAppDied();
assertFalse(mTask.hasChild());
assertFalse(mStack.hasChild());
@@ -1108,13 +1107,13 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testHandleAppDied_RelaunchesAfterCrashDuringFreeResize() {
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(mTask).build();
activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
activity.launchCount = 1;
activity.setSavedState(null /* savedState */);
- mRootWindowContainer.handleAppDied(activity.app);
+ activity.app.handleAppDied();
assertEquals(1, mTask.getChildCount());
assertEquals(1, mStack.getChildCount());
@@ -1122,13 +1121,13 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testHandleAppDied_NotRelaunchAfterThreeCrashesDuringFreeResize() {
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(mTask).build();
activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
activity.launchCount = 3;
activity.setSavedState(null /* savedState */);
- mRootWindowContainer.handleAppDied(activity.app);
+ activity.app.handleAppDied();
assertFalse(mTask.hasChild());
assertFalse(mStack.hasChild());
@@ -1136,11 +1135,11 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testCompletePauseOnResumeWhilePausingActivity() {
- final ActivityRecord bottomActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord bottomActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
doReturn(true).when(bottomActivity).attachedToProcess();
mStack.mPausingActivity = null;
mStack.mResumedActivity = bottomActivity;
- final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.info.flags |= FLAG_RESUME_WHILE_PAUSING;
mStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, topActivity);
@@ -1154,7 +1153,7 @@ public class ActivityStackTests extends ActivityTestsBase {
ActivityRecord activity = homeStack.topRunningActivity();
if (activity == null) {
- activity = new ActivityBuilder(mService)
+ activity = new ActivityBuilder(mAtm)
.setStack(homeStack)
.setCreateTask(true)
.build();
@@ -1265,13 +1264,13 @@ public class ActivityStackTests extends ActivityTestsBase {
public void testNavigateUpTo() {
final ActivityStartController controller = mock(ActivityStartController.class);
final ActivityStarter starter = new ActivityStarter(controller,
- mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
- doReturn(controller).when(mService).getActivityStartController();
+ mAtm, mAtm.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ doReturn(controller).when(mAtm).getActivityStartController();
spyOn(starter);
doReturn(ActivityManager.START_SUCCESS).when(starter).execute();
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(mTask)
.setUid(firstActivity.getUid() + 1).build();
doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString());
@@ -1297,7 +1296,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testShouldUpRecreateTaskLockedWithCorrectAffinityFormat() {
final String affinity = "affinity";
- final ActivityRecord activity = new ActivityBuilder(mService).setAffinity(affinity)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setAffinity(affinity)
.setUid(Binder.getCallingUid()).setCreateTask(true).build();
activity.getTask().affinity = activity.taskAffinity;
@@ -1307,7 +1306,7 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testShouldUpRecreateTaskLockedWithWrongAffinityFormat() {
final String affinity = "affinity";
- final ActivityRecord activity = new ActivityBuilder(mService).setAffinity(affinity)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setAffinity(affinity)
.setUid(Binder.getCallingUid()).setCreateTask(true).build();
activity.getTask().affinity = activity.taskAffinity;
final String fakeAffinity = activity.getUid() + activity.taskAffinity;
@@ -1318,12 +1317,12 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testResetTaskWithFinishingActivities() {
final ActivityRecord taskTop =
- new ActivityBuilder(mService).setStack(mStack).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setStack(mStack).setCreateTask(true).build();
// Make all activities in the task are finishing to simulate Task#getTopActivity
// returns null.
taskTop.finishing = true;
- final ActivityRecord newR = new ActivityBuilder(mService).build();
+ final ActivityRecord newR = new ActivityBuilder(mAtm).build();
final ActivityRecord result = mStack.resetTaskIfNeeded(taskTop, newR);
assertThat(result).isEqualTo(taskTop);
}
@@ -1333,9 +1332,9 @@ public class ActivityStackTests extends ActivityTestsBase {
final ArrayList<ActivityRecord> occludedActivities = new ArrayList<>();
final Consumer<ActivityRecord> handleOccludedActivity = occludedActivities::add;
final ActivityRecord bottomActivity =
- new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setStack(mStack).setTask(mTask).build();
final ActivityRecord topActivity =
- new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setStack(mStack).setTask(mTask).build();
// Top activity occludes bottom activity.
doReturn(true).when(mStack).shouldBeVisible(any());
assertTrue(topActivity.shouldBeVisible());
@@ -1354,7 +1353,7 @@ public class ActivityStackTests extends ActivityTestsBase {
// A finishing activity should not occlude other activities behind.
final ActivityRecord finishingActivity =
- new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setStack(mStack).setTask(mTask).build();
finishingActivity.finishing = true;
doCallRealMethod().when(finishingActivity).occludesParent();
assertTrue(topActivity.shouldBeVisible());
@@ -1376,9 +1375,9 @@ public class ActivityStackTests extends ActivityTestsBase {
final ActivityRecord[] activities = new ActivityRecord[2];
mSupervisor.beginDeferResume();
for (int i = 0; i < activities.length; i++) {
- final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(mTask).build();
activities[i] = r;
- doReturn(null).when(mService).getProcessController(
+ doReturn(null).when(mAtm).getProcessController(
eq(r.processName), eq(r.info.applicationInfo.uid));
r.setState(Task.ActivityState.INITIALIZING, "test");
// Ensure precondition that the activity is opaque.
@@ -1388,7 +1387,7 @@ public class ActivityStackTests extends ActivityTestsBase {
}
mSupervisor.endDeferResume();
- setBooted(mService);
+ setBooted(mAtm);
// 2 activities are started while keyguard is locked, so they are waiting to be resolved.
assertFalse(unknownAppVisibilityController.allResolved());
@@ -1405,8 +1404,8 @@ public class ActivityStackTests extends ActivityTestsBase {
@Test
public void testNonTopVisibleActivityNotResume() {
final ActivityRecord nonTopVisibleActivity =
- new ActivityBuilder(mService).setTask(mTask).build();
- new ActivityBuilder(mService).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setTask(mTask).build();
+ new ActivityBuilder(mAtm).setTask(mTask).build();
doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
doReturn(true).when(nonTopVisibleActivity).shouldBeVisible(anyBoolean(), anyBoolean());
doNothing().when(mSupervisor).startSpecificActivity(any(), anyBoolean(),
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
index c9a927901a37..55afc70f5213 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
@@ -51,7 +51,7 @@ import java.util.Random;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivityStartControllerTests extends ActivityTestsBase {
+public class ActivityStartControllerTests extends WindowTestsBase {
private ActivityStartController mController;
private Factory mFactory;
private ActivityStarter mStarter;
@@ -59,9 +59,9 @@ public class ActivityStartControllerTests extends ActivityTestsBase {
@Before
public void setUp() throws Exception {
mFactory = mock(Factory.class);
- mController = new ActivityStartController(mService, mService.mStackSupervisor, mFactory);
- mStarter = spy(new ActivityStarter(mController, mService,
- mService.mStackSupervisor, mock(ActivityStartInterceptor.class)));
+ mController = new ActivityStartController(mAtm, mAtm.mStackSupervisor, mFactory);
+ mStarter = spy(new ActivityStarter(mController, mAtm,
+ mAtm.mStackSupervisor, mock(ActivityStartInterceptor.class)));
doReturn(mStarter).when(mFactory).obtain();
}
@@ -72,15 +72,15 @@ public class ActivityStartControllerTests extends ActivityTestsBase {
public void testPendingActivityLaunches() {
final Random random = new Random();
- final ActivityRecord activity = new ActivityBuilder(mService).build();
- final ActivityRecord source = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).build();
+ final ActivityRecord source = new ActivityBuilder(mAtm)
.setCreateTask(true)
.build();
final int startFlags = random.nextInt();
- final Task stack = mService.mRootWindowContainer.getDefaultTaskDisplayArea()
+ final Task stack = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final WindowProcessController wpc = new WindowProcessController(mService,
- mService.mContext.getApplicationInfo(), "name", 12345,
+ final WindowProcessController wpc = new WindowProcessController(mAtm,
+ mAtm.mContext.getApplicationInfo(), "name", 12345,
UserHandle.getUserId(12345), mock(Object.class),
mock(WindowProcessListener.class));
wpc.setThread(mock(IApplicationThread.class));
@@ -101,8 +101,8 @@ public class ActivityStartControllerTests extends ActivityTestsBase {
@Test
public void testRecycling() {
final Intent intent = new Intent();
- final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
- mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ final ActivityStarter optionStarter = new ActivityStarter(mController, mAtm,
+ mAtm.mStackSupervisor, mock(ActivityStartInterceptor.class));
optionStarter
.setIntent(intent)
.setReason("Test")
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 d07000f30046..e5c9ecc7676d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -100,7 +100,7 @@ import org.junit.runner.RunWith;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivityStarterTests extends ActivityTestsBase {
+public class ActivityStarterTests extends WindowTestsBase {
private ActivityStartController mController;
private ActivityMetricsLogger mActivityMetricsLogger;
private PackageManagerInternal mMockPackageManager;
@@ -187,7 +187,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
*/
private void verifyStartActivityPreconditionsUntracked(int preconditions, int launchFlags,
int expectedResult) {
- final ActivityTaskManagerService service = mService;
+ final ActivityTaskManagerService service = mAtm;
final IPackageManager packageManager = mock(IPackageManager.class);
final ActivityStartController controller = mock(ActivityStartController.class);
@@ -283,8 +283,8 @@ public class ActivityStarterTests extends ActivityTestsBase {
// Ensure that {@link ActivityOptions} are aborted with unsuccessful result.
if (expectedResult != START_SUCCESS) {
- final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
- mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ final ActivityStarter optionStarter = new ActivityStarter(mController, mAtm,
+ mAtm.mStackSupervisor, mock(ActivityStartInterceptor.class));
final ActivityOptions options = spy(ActivityOptions.makeBasic());
final int optionResult = optionStarter.setCaller(caller)
@@ -338,7 +338,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
invocation -> {
throw new RuntimeException("Not stubbed");
});
- doReturn(mMockPackageManager).when(mService).getPackageManagerInternalLocked();
+ doReturn(mMockPackageManager).when(mAtm).getPackageManagerInternalLocked();
doReturn(false).when(mMockPackageManager).isInstantAppInstallerComponent(any());
doReturn(null).when(mMockPackageManager).resolveIntent(any(), any(), anyInt(), anyInt(),
anyInt(), anyBoolean(), anyInt());
@@ -359,8 +359,8 @@ public class ActivityStarterTests extends ActivityTestsBase {
info.applicationInfo = new ApplicationInfo();
info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName();
- return new ActivityStarter(mController, mService,
- mService.mStackSupervisor, mock(ActivityStartInterceptor.class))
+ return new ActivityStarter(mController, mAtm,
+ mAtm.mStackSupervisor, mock(ActivityStartInterceptor.class))
.setIntent(intent)
.setActivityInfo(info);
}
@@ -373,7 +373,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
public void testCreateTaskLayout() {
// modifier for validating passed values.
final LaunchParamsModifier modifier = mock(LaunchParamsModifier.class);
- mService.mStackSupervisor.getLaunchParamsController().registerModifier(modifier);
+ mAtm.mStackSupervisor.getLaunchParamsController().registerModifier(modifier);
// add custom values to activity info to make unique.
final ActivityInfo info = new ActivityInfo();
@@ -414,9 +414,9 @@ public class ActivityStarterTests extends ActivityTestsBase {
final ActivityStarter starter = prepareStarter(
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP, false);
final ActivityRecord splitPrimaryFocusActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityRecord splitSecondReusableActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
splitPrimaryFocusActivity.getRootTask()
.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
splitSecondReusableActivity.getRootTask()
@@ -443,11 +443,11 @@ public class ActivityStarterTests extends ActivityTestsBase {
final ActivityStarter starter = prepareStarter(
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP, false);
final ActivityRecord splitSecondReusableActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityRecord splitSecondTopActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityRecord splitPrimaryFocusActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
splitPrimaryFocusActivity.getRootTask()
.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
splitSecondReusableActivity.getRootTask()
@@ -475,13 +475,13 @@ public class ActivityStarterTests extends ActivityTestsBase {
*/
@Test
public void testTaskModeViolation() {
- final DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
+ final DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
display.removeAllTasks();
assertNoTasks(display);
final ActivityStarter starter = prepareStarter(0);
- final LockTaskController lockTaskController = mService.getLockTaskController();
+ final LockTaskController lockTaskController = mAtm.getLockTaskController();
doReturn(true).when(lockTaskController).isLockTaskModeViolation(any());
final int result = starter.setReason("testTaskModeViolation").execute();
@@ -504,8 +504,8 @@ public class ActivityStarterTests extends ActivityTestsBase {
*/
@Test
public void testActivityStartsLogging_noLoggingWhenDisabled() {
- doReturn(false).when(mService).isActivityStartsLoggingEnabled();
- doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
+ doReturn(false).when(mAtm).isActivityStartsLoggingEnabled();
+ doReturn(mActivityMetricsLogger).when(mAtm.mStackSupervisor).getActivityMetricsLogger();
ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK);
starter.setReason("testActivityStartsLogging_noLoggingWhenDisabled").execute();
@@ -521,8 +521,8 @@ public class ActivityStarterTests extends ActivityTestsBase {
@Test
public void testActivityStartsLogging_logsWhenEnabled() {
// note: conveniently this package doesn't have any activity visible
- doReturn(true).when(mService).isActivityStartsLoggingEnabled();
- doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
+ doReturn(true).when(mAtm).isActivityStartsLoggingEnabled();
+ doReturn(mActivityMetricsLogger).when(mAtm.mStackSupervisor).getActivityMetricsLogger();
ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
.setCallingUid(FAKE_CALLING_UID)
@@ -544,7 +544,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
*/
@Test
public void testBackgroundActivityStartsAllowed_noStartsAborted() {
- doReturn(true).when(mService).isBackgroundActivityStartsEnabled();
+ doReturn(true).when(mAtm).isBackgroundActivityStartsEnabled();
runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
@@ -558,7 +558,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
*/
@Test
public void testBackgroundActivityStartsDisallowed_unsupportedStartsAborted() {
- doReturn(false).when(mService).isBackgroundActivityStartsEnabled();
+ doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_unsupportedUsecase_aborted", true,
@@ -589,7 +589,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
*/
@Test
public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() {
- doReturn(false).when(mService).isBackgroundActivityStartsEnabled();
+ doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
Process.ROOT_UID, false, PROCESS_STATE_TOP + 1,
@@ -644,13 +644,13 @@ public class ActivityStarterTests extends ActivityTestsBase {
boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
boolean isCallingUidDeviceOwner) {
// window visibility
- doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
+ doReturn(callingUidHasVisibleWindow).when(mAtm.mWindowManager.mRoot)
.isAnyNonToastWindowVisibleForUid(callingUid);
- doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
+ doReturn(realCallingUidHasVisibleWindow).when(mAtm.mWindowManager.mRoot)
.isAnyNonToastWindowVisibleForUid(realCallingUid);
// process importance
- doReturn(callingUidProcState).when(mService).getUidState(callingUid);
- doReturn(realCallingUidProcState).when(mService).getUidState(realCallingUid);
+ doReturn(callingUidProcState).when(mAtm).getUidState(callingUid);
+ doReturn(realCallingUidProcState).when(mAtm).getUidState(realCallingUid);
// foreground activities
final IApplicationThread caller = mock(IApplicationThread.class);
final WindowProcessListener listener = mock(WindowProcessListener.class);
@@ -658,12 +658,12 @@ public class ActivityStarterTests extends ActivityTestsBase {
ai.uid = callingUid;
ai.packageName = "com.android.test.package";
final WindowProcessController callerApp =
- new WindowProcessController(mService, ai, null, callingUid, -1, null, listener);
+ new WindowProcessController(mAtm, ai, null, callingUid, -1, null, listener);
callerApp.setHasForegroundActivities(hasForegroundActivities);
- doReturn(callerApp).when(mService).getProcessController(caller);
+ doReturn(callerApp).when(mAtm).getProcessController(caller);
// caller is recents
RecentTasks recentTasks = mock(RecentTasks.class);
- mService.mStackSupervisor.setRecentTasks(recentTasks);
+ mAtm.mStackSupervisor.setRecentTasks(recentTasks);
doReturn(callerIsRecents).when(recentTasks).isCallerRecents(callingUid);
// caller is temp allowed
if (callerIsTempAllowed) {
@@ -673,7 +673,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
callerApp.setInstrumenting(callerIsInstrumentingWithBackgroundActivityStartPrivileges,
callerIsInstrumentingWithBackgroundActivityStartPrivileges);
// callingUid is the device owner
- doReturn(isCallingUidDeviceOwner).when(mService).isDeviceOwner(callingUid);
+ doReturn(isCallingUidDeviceOwner).when(mAtm).isDeviceOwner(callingUid);
final ActivityOptions options = spy(ActivityOptions.makeBasic());
ActivityRecord[] outActivity = new ActivityRecord[1];
@@ -706,14 +706,14 @@ public class ActivityStarterTests extends ActivityTestsBase {
@Test
public void testBringTaskToFrontWhenFocusedStackIsFinising() {
// Put 2 tasks in the same stack (simulate the behavior of home stack).
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setCreateTask(true).build();
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setStack(activity.getRootTask())
.setCreateTask(true).build();
// Create a top finishing activity.
- final ActivityRecord finishingTopActivity = new ActivityBuilder(mService)
+ final ActivityRecord finishingTopActivity = new ActivityBuilder(mAtm)
.setCreateTask(true).build();
finishingTopActivity.getRootTask().moveToFront("finishingTopActivity");
@@ -741,7 +741,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
// Create a secondary display at bottom.
final TestDisplayContent secondaryDisplay =
- new TestDisplayContent.Builder(mService, 1000, 1500)
+ new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setPosition(POSITION_BOTTOM).build();
final TaskDisplayArea secondaryTaskContainer = secondaryDisplay.getDefaultTaskDisplayArea();
final Task stack = secondaryTaskContainer.createStack(
@@ -751,7 +751,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
final ActivityRecord topActivityOnSecondaryDisplay = createSingleTaskActivityOn(stack);
// Put an activity on default display as the top focused activity.
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
// Start activity with the same intent as {@code topActivityOnSecondaryDisplay}
// on secondary display.
@@ -781,7 +781,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
// Create a secondary display with an activity.
final TestDisplayContent secondaryDisplay =
- new TestDisplayContent.Builder(mService, 1000, 1500).build();
+ new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
mRootWindowContainer.positionChildAt(POSITION_TOP, secondaryDisplay,
false /* includingParents */);
final TaskDisplayArea secondaryTaskContainer = secondaryDisplay.getDefaultTaskDisplayArea();
@@ -793,7 +793,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
final Task topStack = secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
final Task topTask = new TaskBuilder(mSupervisor).setStack(topStack).build();
- new ActivityBuilder(mService).setTask(topTask).build();
+ new ActivityBuilder(mAtm).setTask(topTask).build();
// Start activity with the same intent as {@code singleTaskActivity} on secondary display.
final ActivityOptions options = ActivityOptions.makeBasic()
@@ -815,16 +815,16 @@ public class ActivityStarterTests extends ActivityTestsBase {
final ActivityStarter starter = prepareStarter(
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP, false);
final ActivityRecord reusableActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityRecord topActivity =
- new ActivityBuilder(mService).setCreateTask(true).build();
+ new ActivityBuilder(mAtm).setCreateTask(true).build();
// Make sure topActivity is on top
topActivity.getRootTask().moveToFront("testWasVisibleInRestartAttempt");
reusableActivity.setVisible(false);
final TaskChangeNotificationController taskChangeNotifier =
- mService.getTaskChangeNotificationController();
+ mAtm.getTaskChangeNotificationController();
spyOn(taskChangeNotifier);
Task task = topActivity.getTask();
@@ -853,7 +853,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
.setComponent(componentName)
.setStack(stack)
.build();
- return new ActivityBuilder(mService)
+ return new ActivityBuilder(mAtm)
.setComponent(componentName)
.setLaunchMode(LAUNCH_SINGLE_TASK)
.setTask(task)
@@ -876,7 +876,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
true /* onTop */);
// Put an activity on default display as the top focused activity.
- final ActivityRecord topActivity = new ActivityBuilder(mService)
+ final ActivityRecord topActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setLaunchMode(LAUNCH_SINGLE_TASK)
.build();
@@ -900,7 +900,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
@Test
public void testFreezeTaskListActivityOption() {
RecentTasks recentTasks = mock(RecentTasks.class);
- mService.mStackSupervisor.setRecentTasks(recentTasks);
+ mAtm.mStackSupervisor.setRecentTasks(recentTasks);
doReturn(true).when(recentTasks).isCallerRecents(anyInt());
final ActivityStarter starter = prepareStarter(0 /* flags */);
@@ -922,7 +922,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
@Test
public void testFreezeTaskListActivityOptionFailedStart_expectResetFreezeTaskList() {
RecentTasks recentTasks = mock(RecentTasks.class);
- mService.mStackSupervisor.setRecentTasks(recentTasks);
+ mAtm.mStackSupervisor.setRecentTasks(recentTasks);
doReturn(true).when(recentTasks).isCallerRecents(anyInt());
final ActivityStarter starter = prepareStarter(0 /* flags */);
@@ -959,7 +959,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
intent.setComponent(ActivityBuilder.getDefaultComponent());
doReturn(true).when(mMockPackageManager).isInstantAppInstallerComponent(any());
- starter.setIntent(intent).mRequest.resolveActivity(mService.mStackSupervisor);
+ starter.setIntent(intent).mRequest.resolveActivity(mAtm.mStackSupervisor);
// Make sure the client intent won't be modified.
assertThat(intent.getComponent()).isNotNull();
@@ -985,9 +985,9 @@ public class ActivityStarterTests extends ActivityTestsBase {
@Test
public void testRecycleTaskFromAnotherUser() {
final ActivityStarter starter = prepareStarter(0 /* flags */);
- starter.mStartActivity = new ActivityBuilder(mService).build();
- final Task task = new TaskBuilder(mService.mStackSupervisor)
- .setStack(mService.mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
+ starter.mStartActivity = new ActivityBuilder(mAtm).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor)
+ .setStack(mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
.setUserId(10)
.build();
@@ -1001,7 +1001,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
public void testTargetStackInSplitScreen() {
final ActivityStarter starter =
prepareStarter(FLAG_ACTIVITY_LAUNCH_ADJACENT, false /* mockGetLaunchStack */);
- final ActivityRecord top = new ActivityBuilder(mService).setCreateTask(true).build();
+ final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true).build();
final ActivityOptions options = ActivityOptions.makeBasic();
final ActivityRecord[] outActivity = new ActivityRecord[1];
@@ -1012,7 +1012,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
assertThat(outActivity[0].inSplitScreenWindowingMode()).isFalse();
// Move activity to split-screen-primary stack and make sure it has the focus.
- TestSplitOrganizer splitOrg = new TestSplitOrganizer(mService, top.getDisplayId());
+ TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayId());
top.getRootTask().reparent(splitOrg.mPrimary, POSITION_BOTTOM);
top.getRootTask().moveToFront("testWindowingModeOptionsLaunchAdjacent");
@@ -1026,7 +1026,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
@Test
public void testActivityStart_expectAddedToRecentTask() {
RecentTasks recentTasks = mock(RecentTasks.class);
- mService.mStackSupervisor.setRecentTasks(recentTasks);
+ mAtm.mStackSupervisor.setRecentTasks(recentTasks);
doReturn(true).when(recentTasks).isCallerRecents(anyInt());
final ActivityStarter starter = prepareStarter(0 /* flags */);
@@ -1044,10 +1044,10 @@ public class ActivityStarterTests extends ActivityTestsBase {
starter.setReason("testAllSplitScreenPrimaryActivitiesAreResumed");
- final ActivityRecord targetRecord = new ActivityBuilder(mService).build();
+ final ActivityRecord targetRecord = new ActivityBuilder(mAtm).build();
targetRecord.setFocusable(false);
targetRecord.setVisibility(false);
- final ActivityRecord sourceRecord = new ActivityBuilder(mService).build();
+ final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).build();
final Task stack = spy(
mRootWindowContainer.getDefaultTaskDisplayArea()
@@ -1059,7 +1059,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
doReturn(stack).when(mRootWindowContainer)
.getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
- starter.mStartActivity = new ActivityBuilder(mService).build();
+ starter.mStartActivity = new ActivityBuilder(mAtm).build();
// When
starter.startActivityInner(
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index f8faae66c704..2e988af29638 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -60,14 +60,14 @@ import java.util.ArrayList;
@Presubmit
@MediumTest
@RunWith(WindowTestRunner.class)
-public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
+public class ActivityTaskManagerServiceTests extends WindowTestsBase {
private final ArgumentCaptor<ClientTransaction> mClientTransactionCaptor =
ArgumentCaptor.forClass(ClientTransaction.class);
@Before
public void setUp() throws Exception {
- setBooted(mService);
+ setBooted(mAtm);
}
/** Verify that activity is finished correctly upon request. */
@@ -75,13 +75,13 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
public void testActivityFinish() {
final Task stack = new StackBuilder(mRootWindowContainer).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
- assertTrue("Activity must be finished", mService.finishActivity(activity.appToken,
+ assertTrue("Activity must be finished", mAtm.finishActivity(activity.appToken,
0 /* resultCode */, null /* resultData */,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY));
assertTrue(activity.finishing);
assertTrue("Duplicate activity finish request must also return 'true'",
- mService.finishActivity(activity.appToken, 0 /* resultCode */,
+ mAtm.finishActivity(activity.appToken, 0 /* resultCode */,
null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY));
}
@@ -90,10 +90,10 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
final Task stack = new StackBuilder(mRootWindowContainer).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
final ClientLifecycleManager mockLifecycleManager = mock(ClientLifecycleManager.class);
- doReturn(mockLifecycleManager).when(mService).getLifecycleManager();
+ doReturn(mockLifecycleManager).when(mAtm).getLifecycleManager();
doReturn(true).when(activity).checkEnterPictureInPictureState(anyString(), anyBoolean());
- mService.requestPictureInPictureMode(activity.token);
+ mAtm.requestPictureInPictureMode(activity.token);
verify(mockLifecycleManager).scheduleTransaction(mClientTransactionCaptor.capture());
final ClientTransaction transaction = mClientTransactionCaptor.getValue();
@@ -108,11 +108,11 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
public void testOnPictureInPictureRequested_cannotEnterPip() throws RemoteException {
final Task stack = new StackBuilder(mRootWindowContainer).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
- ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
+ ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doReturn(false).when(activity).inPinnedWindowingMode();
doReturn(false).when(activity).checkEnterPictureInPictureState(anyString(), anyBoolean());
- mService.requestPictureInPictureMode(activity.token);
+ mAtm.requestPictureInPictureMode(activity.token);
// Check enter no transactions with enter pip requests are made.
verify(lifecycleManager, times(0)).scheduleTransaction(any());
@@ -122,10 +122,10 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
public void testOnPictureInPictureRequested_alreadyInPIPMode() throws RemoteException {
final Task stack = new StackBuilder(mRootWindowContainer).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
- ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
+ ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doReturn(true).when(activity).inPinnedWindowingMode();
- mService.requestPictureInPictureMode(activity.token);
+ mAtm.requestPictureInPictureMode(activity.token);
// Check that no transactions with enter pip requests are made.
verify(lifecycleManager, times(0)).scheduleTransaction(any());
@@ -158,14 +158,14 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
@Override
public void onFixedRotationFinished(int displayId) {}
};
- mService.mWindowManager.registerDisplayWindowListener(listener);
+ mAtm.mWindowManager.registerDisplayWindowListener(listener);
// Check that existing displays call added
assertEquals(1, added.size());
assertEquals(0, changed.size());
assertEquals(0, removed.size());
added.clear();
// Check adding a display
- DisplayContent newDisp1 = new TestDisplayContent.Builder(mService, 600, 800).build();
+ DisplayContent newDisp1 = new TestDisplayContent.Builder(mAtm, 600, 800).build();
assertEquals(1, added.size());
assertEquals(0, changed.size());
assertEquals(0, removed.size());
@@ -174,7 +174,7 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
Configuration c = new Configuration(newDisp1.getRequestedOverrideConfiguration());
c.windowConfiguration.setBounds(new Rect(0, 0, 1000, 1300));
newDisp1.onRequestedOverrideConfigurationChanged(c);
- mService.mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
+ mAtm.mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
newDisp1.mDisplayId, false /* markFrozenIfConfigChanged */,
false /* deferResume */);
assertEquals(0, added.size());
@@ -214,13 +214,13 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
//mock other operations
doReturn(true).when(record)
.checkEnterPictureInPictureState("enterPictureInPictureMode", false);
- doReturn(false).when(mService).isInPictureInPictureMode(any());
- doReturn(false).when(mService).isKeyguardLocked();
+ doReturn(false).when(mAtm).isInPictureInPictureMode(any());
+ doReturn(false).when(mAtm).isKeyguardLocked();
//to simulate NPE
doReturn(null).when(record).getParent();
- mService.enterPictureInPictureMode(token, params);
+ mAtm.enterPictureInPictureMode(token, params);
//if record's null parent is not handled gracefully, test will fail with NPE
mockSession.finishMocking();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
deleted file mode 100644
index 5be2f0453bf4..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ /dev/null
@@ -1,607 +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
- */
-
-package com.android.server.wm;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-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.doNothing;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
-
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.IApplicationThread;
-import android.app.WindowConfiguration;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.service.voice.IVoiceInteractionSession;
-import android.view.SurfaceControl;
-import android.window.ITaskOrganizer;
-import android.window.WindowContainerToken;
-
-import com.android.server.AttributeCache;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-
-/**
- * A base class to handle common operations in activity related unit tests.
- */
-class ActivityTestsBase extends SystemServiceTestsBase {
- final Context mContext = getInstrumentation().getTargetContext();
-
- ActivityTaskManagerService mService;
- RootWindowContainer mRootWindowContainer;
- ActivityStackSupervisor mSupervisor;
-
- // Default package name
- static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
-
- // Default base activity name
- private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
-
- @BeforeClass
- public static void setUpOnceBase() {
- AttributeCache.init(getInstrumentation().getTargetContext());
- }
-
- @Before
- public void setUpBase() {
- mService = mSystemServicesTestRule.getActivityTaskManagerService();
- mSupervisor = mService.mStackSupervisor;
- mRootWindowContainer = mService.mRootWindowContainer;
- }
-
- /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */
- TestDisplayContent addNewDisplayContentAt(int position) {
- return new TestDisplayContent.Builder(mService, 1000, 1500).setPosition(position).build();
- }
-
- /** Sets the default minimum task size to 1 so that tests can use small task sizes */
- public void removeGlobalMinSizeRestriction() {
- mService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
- }
-
- /**
- * Builder for creating new activities.
- */
- protected static class ActivityBuilder {
- // An id appended to the end of the component name to make it unique
- private static int sCurrentActivityId = 0;
-
- private final ActivityTaskManagerService mService;
-
- private ComponentName mComponent;
- private String mTargetActivity;
- private Task mTask;
- private String mProcessName = "name";
- private String mAffinity;
- private int mUid = 12345;
- private boolean mCreateTask;
- private Task mStack;
- private int mActivityFlags;
- private int mLaunchMode;
- private int mResizeMode = RESIZE_MODE_RESIZEABLE;
- private float mMaxAspectRatio;
- private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
- private boolean mLaunchTaskBehind;
- private int mConfigChanges;
- private int mLaunchedFromPid;
- private int mLaunchedFromUid;
- private WindowProcessController mWpc;
- private Bundle mIntentExtras;
-
- ActivityBuilder(ActivityTaskManagerService service) {
- mService = service;
- }
-
- ActivityBuilder setComponent(ComponentName component) {
- mComponent = component;
- return this;
- }
-
- ActivityBuilder setTargetActivity(String targetActivity) {
- mTargetActivity = targetActivity;
- return this;
- }
-
- ActivityBuilder setIntentExtras(Bundle extras) {
- mIntentExtras = extras;
- return this;
- }
-
- static ComponentName getDefaultComponent() {
- return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
- DEFAULT_COMPONENT_PACKAGE_NAME);
- }
-
- ActivityBuilder setTask(Task task) {
- mTask = task;
- return this;
- }
-
- ActivityBuilder setActivityFlags(int flags) {
- mActivityFlags = flags;
- return this;
- }
-
- ActivityBuilder setLaunchMode(int launchMode) {
- mLaunchMode = launchMode;
- return this;
- }
-
- ActivityBuilder setStack(Task stack) {
- mStack = stack;
- return this;
- }
-
- ActivityBuilder setCreateTask(boolean createTask) {
- mCreateTask = createTask;
- return this;
- }
-
- ActivityBuilder setProcessName(String name) {
- mProcessName = name;
- return this;
- }
-
- ActivityBuilder setUid(int uid) {
- mUid = uid;
- return this;
- }
-
- ActivityBuilder setResizeMode(int resizeMode) {
- mResizeMode = resizeMode;
- return this;
- }
-
- ActivityBuilder setMaxAspectRatio(float maxAspectRatio) {
- mMaxAspectRatio = maxAspectRatio;
- return this;
- }
-
- ActivityBuilder setScreenOrientation(int screenOrientation) {
- mScreenOrientation = screenOrientation;
- return this;
- }
-
- ActivityBuilder setLaunchTaskBehind(boolean launchTaskBehind) {
- mLaunchTaskBehind = launchTaskBehind;
- return this;
- }
-
- ActivityBuilder setConfigChanges(int configChanges) {
- mConfigChanges = configChanges;
- return this;
- }
-
- ActivityBuilder setLaunchedFromPid(int pid) {
- mLaunchedFromPid = pid;
- return this;
- }
-
- ActivityBuilder setLaunchedFromUid(int uid) {
- mLaunchedFromUid = uid;
- return this;
- }
-
- ActivityBuilder setUseProcess(WindowProcessController wpc) {
- mWpc = wpc;
- return this;
- }
-
- ActivityBuilder setAffinity(String affinity) {
- mAffinity = affinity;
- return this;
- }
-
- ActivityRecord build() {
- SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
- try {
- mService.deferWindowLayout();
- return buildInner();
- } finally {
- mService.continueWindowLayout();
- }
- }
-
- ActivityRecord buildInner() {
- if (mComponent == null) {
- final int id = sCurrentActivityId++;
- mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
- DEFAULT_COMPONENT_CLASS_NAME + id);
- }
-
- if (mCreateTask) {
- mTask = new TaskBuilder(mService.mStackSupervisor)
- .setComponent(mComponent)
- .setStack(mStack).build();
- } else if (mTask == null && mStack != null && DisplayContent.alwaysCreateStack(
- mStack.getWindowingMode(), mStack.getActivityType())) {
- // The stack can be the task root.
- mTask = mStack;
- }
-
- Intent intent = new Intent();
- intent.setComponent(mComponent);
- if (mIntentExtras != null) {
- intent.putExtras(mIntentExtras);
- }
- final ActivityInfo aInfo = new ActivityInfo();
- aInfo.applicationInfo = new ApplicationInfo();
- aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
- aInfo.applicationInfo.packageName = mComponent.getPackageName();
- aInfo.applicationInfo.uid = mUid;
- aInfo.processName = mProcessName;
- aInfo.packageName = mComponent.getPackageName();
- aInfo.name = mComponent.getClassName();
- if (mTargetActivity != null) {
- aInfo.targetActivity = mTargetActivity;
- }
- aInfo.flags |= mActivityFlags;
- aInfo.launchMode = mLaunchMode;
- aInfo.resizeMode = mResizeMode;
- aInfo.maxAspectRatio = mMaxAspectRatio;
- aInfo.screenOrientation = mScreenOrientation;
- aInfo.configChanges |= mConfigChanges;
- aInfo.taskAffinity = mAffinity;
-
- ActivityOptions options = null;
- if (mLaunchTaskBehind) {
- options = ActivityOptions.makeTaskLaunchBehind();
- }
-
- final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
- mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
- null, null, intent, null, aInfo /*aInfo*/, new Configuration(),
- null /* resultTo */, null /* resultWho */, 0 /* reqCode */,
- false /*componentSpecified*/, false /* rootVoiceInteraction */,
- mService.mStackSupervisor, options, null /* sourceRecord */);
- spyOn(activity);
- if (mTask != null) {
- // fullscreen value is normally read from resources in ctor, so for testing we need
- // to set it somewhere else since we can't mock resources.
- doReturn(true).when(activity).occludesParent();
- doReturn(true).when(activity).fillsParent();
- mTask.addChild(activity);
- // Make visible by default...
- activity.setVisible(true);
- }
-
- final WindowProcessController wpc;
- if (mWpc != null) {
- wpc = mWpc;
- } else {
- wpc = new WindowProcessController(mService,
- aInfo.applicationInfo, mProcessName, mUid,
- UserHandle.getUserId(12345), mock(Object.class),
- mock(WindowProcessListener.class));
- wpc.setThread(mock(IApplicationThread.class));
- }
- wpc.setThread(mock(IApplicationThread.class));
- activity.setProcess(wpc);
- doReturn(wpc).when(mService).getProcessController(
- activity.processName, activity.info.applicationInfo.uid);
-
- // Resume top activities to make sure all other signals in the system are connected.
- mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
- return activity;
- }
- }
-
- /**
- * Builder for creating new tasks.
- */
- protected static class TaskBuilder {
- private final ActivityStackSupervisor mSupervisor;
-
- private ComponentName mComponent;
- private String mPackage;
- private int mFlags = 0;
- // Task id 0 is reserved in ARC for the home app.
- private int mTaskId = SystemServicesTestRule.sNextTaskId++;
- private int mUserId = 0;
- private IVoiceInteractionSession mVoiceSession;
- private boolean mCreateStack = true;
-
- private Task mStack;
- private TaskDisplayArea mTaskDisplayArea;
-
- TaskBuilder(ActivityStackSupervisor supervisor) {
- mSupervisor = supervisor;
- }
-
- TaskBuilder setComponent(ComponentName component) {
- mComponent = component;
- return this;
- }
-
- TaskBuilder setPackage(String packageName) {
- mPackage = packageName;
- return this;
- }
-
- /**
- * Set to {@code true} by default, set to {@code false} to prevent the task from
- * automatically creating a parent stack.
- */
- TaskBuilder setCreateStack(boolean createStack) {
- mCreateStack = createStack;
- return this;
- }
-
- TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
- mVoiceSession = session;
- return this;
- }
-
- TaskBuilder setFlags(int flags) {
- mFlags = flags;
- return this;
- }
-
- TaskBuilder setTaskId(int taskId) {
- mTaskId = taskId;
- return this;
- }
-
- TaskBuilder setUserId(int userId) {
- mUserId = userId;
- return this;
- }
-
- TaskBuilder setStack(Task stack) {
- mStack = stack;
- return this;
- }
-
- TaskBuilder setDisplay(DisplayContent display) {
- mTaskDisplayArea = display.getDefaultTaskDisplayArea();
- return this;
- }
-
- Task build() {
- SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
-
- if (mStack == null && mCreateStack) {
- TaskDisplayArea displayArea = mTaskDisplayArea != null ? mTaskDisplayArea
- : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
- mStack = displayArea.createStack(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- spyOn(mStack);
- }
-
- final ActivityInfo aInfo = new ActivityInfo();
- aInfo.applicationInfo = new ApplicationInfo();
- aInfo.applicationInfo.packageName = mPackage;
-
- Intent intent = new Intent();
- if (mComponent == null) {
- mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
- DEFAULT_COMPONENT_CLASS_NAME);
- }
-
- intent.setComponent(mComponent);
- intent.setFlags(mFlags);
-
- final Task task = new Task(mSupervisor.mService, mTaskId, aInfo,
- intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
- null /*taskDescription*/, mStack);
- spyOn(task);
- task.mUserId = mUserId;
-
- if (mStack != null) {
- mStack.moveToFront("test");
- mStack.addChild(task, true, true);
- }
-
- return task;
- }
- }
-
- static class StackBuilder {
- private final RootWindowContainer mRootWindowContainer;
- private DisplayContent mDisplay;
- private TaskDisplayArea mTaskDisplayArea;
- private int mStackId = -1;
- private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
- private int mActivityType = ACTIVITY_TYPE_STANDARD;
- private boolean mOnTop = true;
- private boolean mCreateActivity = true;
- private ActivityInfo mInfo;
- private Intent mIntent;
-
- StackBuilder(RootWindowContainer root) {
- mRootWindowContainer = root;
- mDisplay = mRootWindowContainer.getDefaultDisplay();
- mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
- }
-
- StackBuilder setWindowingMode(int windowingMode) {
- mWindowingMode = windowingMode;
- return this;
- }
-
- StackBuilder setActivityType(int activityType) {
- mActivityType = activityType;
- return this;
- }
-
- StackBuilder setStackId(int stackId) {
- mStackId = stackId;
- return this;
- }
-
- /**
- * Set the parent {@link DisplayContent} and use the default task display area. Overrides
- * the task display area, if was set before.
- */
- StackBuilder setDisplay(DisplayContent display) {
- mDisplay = display;
- mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
- return this;
- }
-
- /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
- StackBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
- mTaskDisplayArea = taskDisplayArea;
- mDisplay = mTaskDisplayArea.mDisplayContent;
- return this;
- }
-
- StackBuilder setOnTop(boolean onTop) {
- mOnTop = onTop;
- return this;
- }
-
- StackBuilder setCreateActivity(boolean createActivity) {
- mCreateActivity = createActivity;
- return this;
- }
-
- StackBuilder setActivityInfo(ActivityInfo info) {
- mInfo = info;
- return this;
- }
-
- StackBuilder setIntent(Intent intent) {
- mIntent = intent;
- return this;
- }
-
- Task build() {
- SystemServicesTestRule.checkHoldsLock(mRootWindowContainer.mWmService.mGlobalLock);
-
- final int stackId = mStackId >= 0 ? mStackId : mTaskDisplayArea.getNextStackId();
- final Task stack = mTaskDisplayArea.createStackUnchecked(
- mWindowingMode, mActivityType, stackId, mOnTop, mInfo, mIntent,
- false /* createdByOrganizer */);
- final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor;
-
- if (mCreateActivity) {
- new ActivityBuilder(supervisor.mService)
- .setCreateTask(true)
- .setStack(stack)
- .build();
- if (mOnTop) {
- // We move the task to front again in order to regain focus after activity
- // added to the stack. Or {@link DisplayContent#mPreferredTopFocusableStack}
- // could be other stacks (e.g. home stack).
- stack.moveToFront("createActivityStack");
- } else {
- stack.moveToBack("createActivityStack", null);
- }
- }
- spyOn(stack);
-
- doNothing().when(stack).startActivityLocked(
- any(), any(), anyBoolean(), anyBoolean(), any());
-
- return stack;
- }
-
- }
-
- static class TestSplitOrganizer extends ITaskOrganizer.Stub {
- final ActivityTaskManagerService mService;
- Task mPrimary;
- Task mSecondary;
- boolean mInSplit = false;
- // moves everything to secondary. Most tests expect this since sysui usually does it.
- boolean mMoveToSecondaryOnEnter = true;
- int mDisplayId;
- TestSplitOrganizer(ActivityTaskManagerService service, int displayId) {
- mService = service;
- mDisplayId = displayId;
- mService.mTaskOrganizerController.registerTaskOrganizer(this,
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- mService.mTaskOrganizerController.registerTaskOrganizer(this,
- WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask(
- displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
- mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask();
- WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask(
- displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
- mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask();
- }
- TestSplitOrganizer(ActivityTaskManagerService service) {
- this(service,
- service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay().mDisplayId);
- }
- public void setMoveToSecondaryOnEnter(boolean move) {
- mMoveToSecondaryOnEnter = move;
- }
- @Override
- public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
- }
- @Override
- public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
- }
- @Override
- public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
- if (mInSplit) {
- return;
- }
- if (info.topActivityType == ACTIVITY_TYPE_UNDEFINED) {
- // Not populated
- return;
- }
- if (info.configuration.windowConfiguration.getWindowingMode()
- != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- return;
- }
- mInSplit = true;
- if (!mMoveToSecondaryOnEnter) {
- return;
- }
- mService.mTaskOrganizerController.setLaunchRoot(mDisplayId,
- mSecondary.mRemoteToken.toWindowContainerToken());
- DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
- dc.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
- if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) {
- stack.reparent(mSecondary, POSITION_BOTTOM);
- }
- }
- });
- }
- @Override
- public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
- }
- };
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index d7baf8d05bd6..7adceade0b9b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -129,36 +129,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
@Test
- public void testGetAnimationTargets_noHierarchicalAnimations() {
- WindowManagerService.sHierarchicalAnimations = false;
-
- // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, invisible)
- // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, visible)
- final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
- final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1);
- activity1.setVisible(false);
- activity1.mVisibleRequested = true;
-
- final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
- final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2);
-
- final ArraySet<ActivityRecord> opening = new ArraySet<>();
- opening.add(activity1);
- final ArraySet<ActivityRecord> closing = new ArraySet<>();
- closing.add(activity2);
-
- // Don't promote when the flag is disabled.
- assertEquals(
- new ArraySet<>(new WindowContainer[]{activity1}),
- AppTransitionController.getAnimationTargets(
- opening, closing, true /* visible */));
- assertEquals(
- new ArraySet<>(new WindowContainer[]{activity2}),
- AppTransitionController.getAnimationTargets(
- opening, closing, false /* visible */));
- }
-
- @Test
public void testGetAnimationTargets_visibilityAlreadyUpdated() {
// [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, visible)
// +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible)
@@ -177,17 +147,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// No animation, since visibility of the opening and closing apps are already updated
// outside of AppTransition framework.
- WindowManagerService.sHierarchicalAnimations = false;
- assertEquals(
- new ArraySet<>(),
- AppTransitionController.getAnimationTargets(
- opening, closing, true /* visible */));
- assertEquals(
- new ArraySet<>(),
- AppTransitionController.getAnimationTargets(
- opening, closing, false /* visible */));
-
- WindowManagerService.sHierarchicalAnimations = true;
assertEquals(
new ArraySet<>(),
AppTransitionController.getAnimationTargets(
@@ -221,13 +180,12 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// The visibility are already updated, but since forced transition is requested, it will
// be included.
- WindowManagerService.sHierarchicalAnimations = false;
assertEquals(
- new ArraySet<>(new WindowContainer[]{activity1}),
+ new ArraySet<>(new WindowContainer[]{activity1.getStack()}),
AppTransitionController.getAnimationTargets(
opening, closing, true /* visible */));
assertEquals(
- new ArraySet<>(new WindowContainer[]{activity2}),
+ new ArraySet<>(new WindowContainer[]{activity2.getStack()}),
AppTransitionController.getAnimationTargets(
opening, closing, false /* visible */));
}
@@ -247,13 +205,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// Animate closing apps even if it's not visible when it is exiting before we had a chance
// to play the transition animation.
- WindowManagerService.sHierarchicalAnimations = false;
- assertEquals(
- new ArraySet<>(new WindowContainer[]{activity}),
- AppTransitionController.getAnimationTargets(
- new ArraySet<>(), closing, false /* visible */));
-
- WindowManagerService.sHierarchicalAnimations = true;
assertEquals(
new ArraySet<>(new WindowContainer[]{stack}),
AppTransitionController.getAnimationTargets(
@@ -292,17 +243,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// Animate opening apps even if it's already visible in case its windows are being replaced.
// Don't animate closing apps if it's already invisible even though its windows are being
// replaced.
- WindowManagerService.sHierarchicalAnimations = false;
- assertEquals(
- new ArraySet<>(new WindowContainer[]{activity1}),
- AppTransitionController.getAnimationTargets(
- opening, closing, true /* visible */));
- assertEquals(
- new ArraySet<>(new WindowContainer[]{}),
- AppTransitionController.getAnimationTargets(
- opening, closing, false /* visible */));
-
- WindowManagerService.sHierarchicalAnimations = true;
assertEquals(
new ArraySet<>(new WindowContainer[]{stack1}),
AppTransitionController.getAnimationTargets(
@@ -315,8 +255,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testGetAnimationTargets_openingClosingInDifferentTask() {
- WindowManagerService.sHierarchicalAnimations = true;
-
// [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
// | +- [ActivityRecord2] (invisible)
// |
@@ -361,8 +299,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testGetAnimationTargets_openingClosingInSameTask() {
- WindowManagerService.sHierarchicalAnimations = true;
-
// [DisplayContent] - [TaskStack] - [Task] -+- [ActivityRecord1] (opening, invisible)
// +- [ActivityRecord2] (closing, visible)
final Task stack = createTaskStackOnDisplay(mDisplayContent);
@@ -393,8 +329,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testGetAnimationTargets_animateOnlyTranslucentApp() {
- WindowManagerService.sHierarchicalAnimations = true;
-
// [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
// | +- [ActivityRecord2] (visible)
// |
@@ -439,8 +373,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testGetAnimationTargets_animateTranslucentAndOpaqueApps() {
- WindowManagerService.sHierarchicalAnimations = true;
-
// [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
// | +- [ActivityRecord2] (opening, invisible)
// |
@@ -489,8 +421,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testGetAnimationTargets_stackContainsMultipleTasks() {
- WindowManagerService.sHierarchicalAnimations = true;
-
// [DisplayContent] - [TaskStack] -+- [Task1] - [ActivityRecord1] (opening, invisible)
// +- [Task2] - [ActivityRecord2] (closing, visible)
final Task stack = createTaskStackOnDisplay(mDisplayContent);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 97a2ebe98abb..888935ef9747 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -431,7 +431,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
doCallRealMethod().when(mStack).startActivityLocked(
any(), any(), anyBoolean(), anyBoolean(), any());
// Make mVisibleSetFromTransferredStartingWindow true.
- final ActivityRecord middle = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ final ActivityRecord middle = new ActivityBuilder(mWm.mAtmService)
.setTask(mTask).build();
mStack.startActivityLocked(middle, null /* focusedTopActivity */,
false /* newTask */, false /* keepCurTransition */, null /* options */);
@@ -440,7 +440,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
assertNull(mActivity.startingWindow);
assertHasStartingWindow(middle);
- final ActivityRecord top = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ final ActivityRecord top = new ActivityBuilder(mWm.mAtmService)
.setTask(mTask).build();
// Expect the visibility should be updated to true when transferring starting window from
// a visible activity.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 96ea64667f6e..0cc61599c2ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -850,13 +850,13 @@ public class DisplayContentTests extends WindowTestsBase {
IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
final Task stack =
- new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
+ new StackBuilder(mWm.mAtmService.mRootWindowContainer)
.setDisplay(dc)
.build();
doReturn(true).when(stack).isVisible();
final Task freeformStack =
- new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
+ new StackBuilder(mWm.mAtmService.mRootWindowContainer)
.setDisplay(dc)
.setWindowingMode(WINDOWING_MODE_FREEFORM)
.build();
@@ -881,9 +881,8 @@ public class DisplayContentTests extends WindowTestsBase {
IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
final int newOrientation = getRotatedOrientation(dc);
- final Task stack =
- new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
- .setDisplay(dc).build();
+ final Task stack = new StackBuilder(mWm.mAtmService.mRootWindowContainer)
+ .setDisplay(dc).build();
final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
@@ -901,9 +900,8 @@ public class DisplayContentTests extends WindowTestsBase {
IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
final int newOrientation = getRotatedOrientation(dc);
- final Task stack =
- new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
- .setDisplay(dc).build();
+ final Task stack = new StackBuilder(mWm.mAtmService.mRootWindowContainer)
+ .setDisplay(dc).build();
final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
@@ -1213,7 +1211,7 @@ public class DisplayContentTests extends WindowTestsBase {
verify(t, never()).setPosition(any(), eq(0), eq(0));
// Launch another activity before the transition is finished.
- final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final ActivityRecord app2 = new StackBuilder(mWm.mRoot)
.setDisplay(mDisplayContent).build().getTopMostActivity();
app2.setVisible(false);
mDisplayContent.mOpeningApps.add(app2);
@@ -1247,8 +1245,7 @@ public class DisplayContentTests extends WindowTestsBase {
final ActivityRecord app = createActivityRecord(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD);
final Task task = app.getTask();
- final ActivityRecord app2 = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
- .setTask(task).build();
+ final ActivityRecord app2 = new ActivityBuilder(mWm.mAtmService).setTask(task).build();
mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4);
doReturn(true).when(task).isAppTransitioning();
// If the task is animating transition, this should be no-op.
@@ -1354,7 +1351,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertFalse(displayRotation.updateRotationUnchecked(false));
// Rotation can be updated if the recents animation is finished.
- mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(false);
+ mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
assertTrue(displayRotation.updateRotationUnchecked(false));
// Rotation can be updated if the recents animation is animating but it is not on top, e.g.
@@ -1513,8 +1510,7 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testSetWindowingModeAtomicallyUpdatesWindoingModeAndDisplayWindowingMode() {
final DisplayContent dc = createNewDisplay();
- final Task stack =
- new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
+ final Task stack = new StackBuilder(mWm.mAtmService.mRootWindowContainer)
.setDisplay(dc)
.build();
doAnswer(invocation -> {
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 a7a8505e336d..820eca4a49a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
@@ -68,14 +68,14 @@ import java.util.Map;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class LaunchParamsControllerTests extends ActivityTestsBase {
+public class LaunchParamsControllerTests extends WindowTestsBase {
private LaunchParamsController mController;
private TestLaunchParamsPersister mPersister;
@Before
public void setUp() throws Exception {
mPersister = new TestLaunchParamsPersister();
- mController = new LaunchParamsController(mService, mPersister);
+ mController = new LaunchParamsController(mAtm, mPersister);
}
/**
@@ -87,8 +87,8 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
positioner = mock(LaunchParamsModifier.class);
mController.registerModifier(positioner);
- final ActivityRecord record = new ActivityBuilder(mService).build();
- final ActivityRecord source = new ActivityBuilder(mService).build();
+ final ActivityRecord record = new ActivityBuilder(mAtm).build();
+ 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);
@@ -108,7 +108,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
final ComponentName name = new ComponentName("com.android.foo", ".BarActivity");
final int userId = 0;
- final ActivityRecord activity = new ActivityBuilder(mService).setComponent(name)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setComponent(name)
.setUid(userId).build();
final LaunchParams expected = new LaunchParams();
expected.mPreferredTaskDisplayArea = mock(TaskDisplayArea.class);
@@ -228,10 +228,10 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
@Test
public void testVrPreferredDisplay() {
final TestDisplayContent vrDisplay = createNewDisplayContent();
- mService.mVr2dDisplayId = vrDisplay.mDisplayId;
+ mAtm.mVr2dDisplayId = vrDisplay.mDisplayId;
final LaunchParams result = new LaunchParams();
- final ActivityRecord vrActivity = new ActivityBuilder(mService).build();
+ final ActivityRecord vrActivity = new ActivityBuilder(mAtm).build();
vrActivity.requestedVrComponent = vrActivity.mActivityComponent;
// VR activities should always land on default display.
@@ -241,7 +241,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
result.mPreferredTaskDisplayArea);
// Otherwise, always lands on VR 2D display.
- final ActivityRecord vr2dActivity = new ActivityBuilder(mService).build();
+ final ActivityRecord vr2dActivity = new ActivityBuilder(mAtm).build();
mController.calculate(null /*task*/, null /*layout*/, vr2dActivity /*activity*/,
null /*source*/, null /*options*/, PHASE_BOUNDS, result);
assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea);
@@ -249,7 +249,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
null /*options*/, PHASE_BOUNDS, result);
assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea);
- mService.mVr2dDisplayId = INVALID_DISPLAY;
+ mAtm.mVr2dDisplayId = INVALID_DISPLAY;
}
@@ -262,8 +262,8 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
final LaunchParamsModifier positioner = mock(LaunchParamsModifier.class);
mController.registerModifier(positioner);
- final ActivityRecord record = new ActivityBuilder(mService).build();
- final ActivityRecord source = new ActivityBuilder(mService).build();
+ final ActivityRecord record = new ActivityBuilder(mAtm).build();
+ 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);
@@ -284,7 +284,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
final TaskDisplayArea preferredTaskDisplayArea = display.getDefaultTaskDisplayArea();
params.mPreferredTaskDisplayArea = preferredTaskDisplayArea;
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
- final Task task = new TaskBuilder(mService.mStackSupervisor).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor).build();
mController.registerModifier(positioner);
@@ -305,7 +305,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
final int windowingMode = WINDOWING_MODE_FREEFORM;
params.mWindowingMode = windowingMode;
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
- final Task task = new TaskBuilder(mService.mStackSupervisor).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor).build();
mController.registerModifier(positioner);
@@ -330,7 +330,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
params.mWindowingMode = WINDOWING_MODE_FREEFORM;
params.mBounds.set(expected);
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
- final Task task = new TaskBuilder(mService.mStackSupervisor).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor).build();
mController.registerModifier(positioner);
@@ -355,7 +355,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
params.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
params.mBounds.set(expected);
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
- final Task task = new TaskBuilder(mService.mStackSupervisor).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor).build();
mController.registerModifier(positioner);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index e389a538f25d..18a2d1337d4b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -65,7 +65,7 @@ import java.util.function.Predicate;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class LaunchParamsPersisterTests extends ActivityTestsBase {
+public class LaunchParamsPersisterTests extends WindowTestsBase {
private static final int TEST_USER_ID = 3;
private static final int ALTERNATIVE_USER_ID = 0;
private static final ComponentName TEST_COMPONENT =
@@ -109,7 +109,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase {
deleteRecursively(mFolder);
mDisplayUniqueId = "test:" + sNextUniqueId++;
- mTestDisplay = new TestDisplayContent.Builder(mService, 1000, 1500)
+ mTestDisplay = new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setUniqueId(mDisplayUniqueId).build();
when(mRootWindowContainer.getDisplayContent(eq(mDisplayUniqueId)))
.thenReturn(mTestDisplay);
@@ -172,7 +172,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase {
public void testFetchesSameResultWithActivity() {
mTarget.saveTask(mTestTask);
- final ActivityRecord activity = new ActivityBuilder(mService).setComponent(TEST_COMPONENT)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setComponent(TEST_COMPONENT)
.setUid(TEST_USER_ID * UserHandle.PER_USER_RANGE).build();
mTarget.getLaunchParams(null, activity, mResult);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 1724303633d9..54c7f271e81b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -94,7 +94,7 @@ import java.util.function.Function;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class RecentTasksTest extends ActivityTestsBase {
+public class RecentTasksTest extends WindowTestsBase {
private static final int TEST_USER_0_ID = 0;
private static final int TEST_USER_1_ID = 10;
private static final int TEST_QUIET_USER_ID = 20;
@@ -122,14 +122,14 @@ public class RecentTasksTest extends ActivityTestsBase {
mTaskContainer = mRootWindowContainer.getDefaultTaskDisplayArea();
// Set the recent tasks we should use for testing in this class.
- mRecentTasks = new TestRecentTasks(mService, mTaskPersister);
+ mRecentTasks = new TestRecentTasks(mAtm, mTaskPersister);
spyOn(mRecentTasks);
- mService.setRecentTasks(mRecentTasks);
+ mAtm.setRecentTasks(mRecentTasks);
mRecentTasks.loadParametersFromResources(mContext.getResources());
// Set the running tasks we should use for testing in this class.
mRunningTasks = new TestRunningTasks();
- mService.mStackSupervisor.setRunningTasks(mRunningTasks);
+ mAtm.mStackSupervisor.setRunningTasks(mRunningTasks);
mStack = mTaskContainer.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
@@ -455,7 +455,7 @@ public class RecentTasksTest extends ActivityTestsBase {
final Function<Boolean, Task> taskBuilder = visible -> {
final Task task = createTaskBuilder(className).build();
// Make the task non-empty.
- final ActivityRecord r = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(task).build();
r.setVisibility(visible);
return task;
};
@@ -831,7 +831,7 @@ public class RecentTasksTest extends ActivityTestsBase {
Task stack = mTasks.get(2).getRootTask();
stack.moveToFront("", mTasks.get(2));
- doReturn(stack).when(mService.mRootWindowContainer).getTopDisplayFocusedStack();
+ doReturn(stack).when(mAtm.mRootWindowContainer).getTopDisplayFocusedStack();
// Simulate the reset from the timeout
mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
@@ -994,16 +994,16 @@ public class RecentTasksTest extends ActivityTestsBase {
mStack.removeIfPossible();
// The following APIs should not restore task from recents to the active list.
- assertNotRestoreTask(() -> mService.setFocusedTask(taskId));
- assertNotRestoreTask(() -> mService.startSystemLockTaskMode(taskId));
- assertNotRestoreTask(() -> mService.cancelTaskWindowTransition(taskId));
+ assertNotRestoreTask(() -> mAtm.setFocusedTask(taskId));
+ assertNotRestoreTask(() -> mAtm.startSystemLockTaskMode(taskId));
+ assertNotRestoreTask(() -> mAtm.cancelTaskWindowTransition(taskId));
assertNotRestoreTask(
- () -> mService.resizeTask(taskId, null /* bounds */, 0 /* resizeMode */));
+ () -> mAtm.resizeTask(taskId, null /* bounds */, 0 /* resizeMode */));
assertNotRestoreTask(
- () -> mService.setTaskWindowingMode(taskId, WINDOWING_MODE_FULLSCREEN,
+ () -> mAtm.setTaskWindowingMode(taskId, WINDOWING_MODE_FULLSCREEN,
false/* toTop */));
assertNotRestoreTask(
- () -> mService.setTaskWindowingModeSplitScreenPrimary(taskId, false /* toTop */));
+ () -> mAtm.setTaskWindowingModeSplitScreenPrimary(taskId, false /* toTop */));
}
@Test
@@ -1014,7 +1014,7 @@ public class RecentTasksTest extends ActivityTestsBase {
mRecentTasks.remove(task);
TaskChangeNotificationController controller =
- mService.getTaskChangeNotificationController();
+ mAtm.getTaskChangeNotificationController();
verify(controller, times(2)).notifyTaskListUpdated();
}
@@ -1027,7 +1027,7 @@ public class RecentTasksTest extends ActivityTestsBase {
// 2 calls - Once for add and once for remove
TaskChangeNotificationController controller =
- mService.getTaskChangeNotificationController();
+ mAtm.getTaskChangeNotificationController();
verify(controller, times(2)).notifyTaskListUpdated();
}
@@ -1042,7 +1042,7 @@ public class RecentTasksTest extends ActivityTestsBase {
// 4 calls - Twice for add and twice for remove
TaskChangeNotificationController controller =
- mService.getTaskChangeNotificationController();
+ mAtm.getTaskChangeNotificationController();
verify(controller, times(4)).notifyTaskListUpdated();
}
@@ -1054,7 +1054,7 @@ public class RecentTasksTest extends ActivityTestsBase {
final Bundle data = new Bundle();
data.putInt("key", 100);
final Task task1 = createTaskBuilder(".Task").build();
- final ActivityRecord r1 = new ActivityBuilder(mService)
+ final ActivityRecord r1 = new ActivityBuilder(mAtm)
.setTask(task1)
.setIntentExtras(data)
.build();
@@ -1106,7 +1106,7 @@ public class RecentTasksTest extends ActivityTestsBase {
@Test
public void testNotRecentsComponent_denyApiAccess() throws Exception {
- doReturn(PackageManager.PERMISSION_DENIED).when(mService)
+ doReturn(PackageManager.PERMISSION_DENIED).when(mAtm)
.checkGetTasksPermission(anyString(), anyInt(), anyInt());
// Expect the following methods to fail due to recents component not being set
mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.DENY_THROW_SECURITY_EXCEPTION);
@@ -1118,7 +1118,7 @@ public class RecentTasksTest extends ActivityTestsBase {
@Test
public void testRecentsComponent_allowApiAccessWithoutPermissions() {
- doReturn(PackageManager.PERMISSION_DENIED).when(mService)
+ doReturn(PackageManager.PERMISSION_DENIED).when(mAtm)
.checkGetTasksPermission(anyString(), anyInt(), anyInt());
// Set the recents component and ensure that the following calls do not fail
mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.GRANT);
@@ -1127,50 +1127,50 @@ public class RecentTasksTest extends ActivityTestsBase {
}
private void doTestRecentTasksApis(boolean expectCallable) {
- assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID));
+ assertSecurityException(expectCallable, () -> mAtm.removeStack(INVALID_STACK_ID));
assertSecurityException(expectCallable,
- () -> mService.removeStacksInWindowingModes(
+ () -> mAtm.removeStacksInWindowingModes(
new int[]{WINDOWING_MODE_UNDEFINED}));
assertSecurityException(expectCallable,
- () -> mService.removeStacksWithActivityTypes(
+ () -> mAtm.removeStacksWithActivityTypes(
new int[]{ACTIVITY_TYPE_UNDEFINED}));
- assertSecurityException(expectCallable, () -> mService.removeTask(0));
+ assertSecurityException(expectCallable, () -> mAtm.removeTask(0));
assertSecurityException(expectCallable,
- () -> mService.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true));
+ () -> mAtm.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true));
assertSecurityException(expectCallable,
- () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true));
+ () -> mAtm.moveTaskToStack(0, INVALID_STACK_ID, true));
assertSecurityException(expectCallable,
- () -> mService.setTaskWindowingModeSplitScreenPrimary(0, true));
+ () -> mAtm.setTaskWindowingModeSplitScreenPrimary(0, true));
assertSecurityException(expectCallable,
- () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
- assertSecurityException(expectCallable, () -> mService.getAllStackInfos());
+ () -> mAtm.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
+ assertSecurityException(expectCallable, () -> mAtm.getAllStackInfos());
assertSecurityException(expectCallable,
- () -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
+ () -> mAtm.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
assertSecurityException(expectCallable, () -> {
try {
- mService.getFocusedStackInfo();
+ mAtm.getFocusedStackInfo();
} catch (RemoteException e) {
// Ignore
}
});
assertSecurityException(expectCallable,
- () -> mService.startActivityFromRecents(0, new Bundle()));
- assertSecurityException(expectCallable, () -> mService.getTaskSnapshot(0, true));
- assertSecurityException(expectCallable, () -> mService.registerTaskStackListener(null));
+ () -> mAtm.startActivityFromRecents(0, new Bundle()));
+ assertSecurityException(expectCallable, () -> mAtm.getTaskSnapshot(0, true));
+ assertSecurityException(expectCallable, () -> mAtm.registerTaskStackListener(null));
assertSecurityException(expectCallable,
- () -> mService.unregisterTaskStackListener(null));
- assertSecurityException(expectCallable, () -> mService.getTaskDescription(0));
- assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0));
- assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null,
+ () -> mAtm.unregisterTaskStackListener(null));
+ assertSecurityException(expectCallable, () -> mAtm.getTaskDescription(0));
+ assertSecurityException(expectCallable, () -> mAtm.cancelTaskWindowTransition(0));
+ assertSecurityException(expectCallable, () -> mAtm.startRecentsActivity(null, null,
null));
- assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation(true));
- assertSecurityException(expectCallable, () -> mService.stopAppSwitches());
- assertSecurityException(expectCallable, () -> mService.resumeAppSwitches());
+ assertSecurityException(expectCallable, () -> mAtm.cancelRecentsAnimation(true));
+ assertSecurityException(expectCallable, () -> mAtm.stopAppSwitches());
+ assertSecurityException(expectCallable, () -> mAtm.resumeAppSwitches());
}
private void testGetTasksApis(boolean expectCallable) {
- mService.getRecentTasks(MAX_VALUE, 0, TEST_USER_0_ID);
- mService.getTasks(MAX_VALUE);
+ mAtm.getRecentTasks(MAX_VALUE, 0, TEST_USER_0_ID);
+ mAtm.getTasks(MAX_VALUE);
if (expectCallable) {
assertTrue(mRecentTasks.mLastAllowed);
assertTrue(mRunningTasks.mLastAllowed);
@@ -1185,7 +1185,7 @@ public class RecentTasksTest extends ActivityTestsBase {
}
private TaskBuilder createTaskBuilder(String packageName, String className) {
- return new TaskBuilder(mService.mStackSupervisor)
+ return new TaskBuilder(mAtm.mStackSupervisor)
.setComponent(new ComponentName(packageName, className))
.setStack(mStack)
.setUserId(TEST_USER_0_ID);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 695a0e3881ea..7fb7d40f0bd2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -362,13 +362,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
assertFalse(homeActivity.hasFixedRotationTransform());
}
- @Test
- public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
- unblockDisplayRotation(mDefaultDisplay);
+ private ActivityRecord prepareFixedRotationLaunchingAppWithRecentsAnim() {
final ActivityRecord homeActivity = createHomeActivity();
homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ // Add a window so it can be animated by the recents.
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
+ activity.addWindow(win);
// Assume an activity is launching to different rotation.
mDefaultDisplay.setFixedRotationLaunchingApp(activity,
(mDefaultDisplay.getRotation() + 1) % 4);
@@ -379,6 +380,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
// Before the transition is done, the recents animation is triggered.
initializeRecentsAnimationController(mController, homeActivity);
assertFalse(homeActivity.hasFixedRotationTransform());
+ assertTrue(mController.isAnimatingTask(activity.getTask()));
+
+ return activity;
+ }
+
+ @Test
+ public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
+ final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim();
// Simulate giving up the swipe up gesture to keep the original activity as top.
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
@@ -388,6 +397,21 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
@Test
+ public void testKeepFixedRotationWhenMovingRecentsToTop() {
+ final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim();
+ // Assume a transition animation has started running before recents animation. Then the
+ // activity will receive onAnimationFinished that notifies app transition finished when
+ // removing the recents animation of task.
+ activity.getTask().getAnimationSources().add(activity);
+
+ // Simulate swiping to home/recents before the transition is done.
+ mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
+ // The rotation transform should be preserved. In real case, it will be cleared by the next
+ // move-to-top transition.
+ assertTrue(activity.hasFixedRotationTransform());
+ }
+
+ @Test
public void testWallpaperHasFixedRotationApplied() {
unblockDisplayRotation(mDefaultDisplay);
mWm.setRecentsAnimationController(mController);
@@ -453,7 +477,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
private ActivityRecord createHomeActivity() {
- final ActivityRecord homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
.setStack(mRootHomeTask)
.setCreateTask(true)
.build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index e5d1e465d8ff..d821d38ea297 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -66,7 +66,7 @@ import org.junit.runner.RunWith;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class RecentsAnimationTest extends ActivityTestsBase {
+public class RecentsAnimationTest extends WindowTestsBase {
private static final int TEST_USER_ID = 100;
@@ -77,11 +77,11 @@ public class RecentsAnimationTest extends ActivityTestsBase {
@Before
public void setUp() throws Exception {
mRecentsAnimationController = mock(RecentsAnimationController.class);
- mService.mWindowManager.setRecentsAnimationController(mRecentsAnimationController);
- doNothing().when(mService.mWindowManager).initializeRecentsAnimation(
+ mAtm.mWindowManager.setRecentsAnimationController(mRecentsAnimationController);
+ doNothing().when(mAtm.mWindowManager).initializeRecentsAnimation(
anyInt(), any(), any(), anyInt(), any(), any());
- final RecentTasks recentTasks = mService.getRecentTasks();
+ final RecentTasks recentTasks = mAtm.getRecentTasks();
spyOn(recentTasks);
doReturn(mRecentsComponent).when(recentTasks).getRecentsComponent();
}
@@ -91,12 +91,12 @@ public class RecentsAnimationTest extends ActivityTestsBase {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
- ActivityRecord recentActivity = new ActivityBuilder(mService)
+ ActivityRecord recentActivity = new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent)
.setCreateTask(true)
.setStack(recentsStack)
.build();
- ActivityRecord topActivity = new ActivityBuilder(mService).setCreateTask(true).build();
+ ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility");
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
@@ -123,7 +123,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
false /* includingParents */);
ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
if (topRunningHomeActivity == null) {
- topRunningHomeActivity = new ActivityBuilder(mService)
+ topRunningHomeActivity = new ActivityBuilder(mAtm)
.setStack(homeStack)
.setCreateTask(true)
.build();
@@ -139,15 +139,15 @@ public class RecentsAnimationTest extends ActivityTestsBase {
anyInt() /* startFlags */, any() /* profilerInfo */);
// Assume its process is alive because the caller should be the recents service.
- WindowProcessController wpc = new WindowProcessController(mService, aInfo.applicationInfo,
+ WindowProcessController wpc = new WindowProcessController(mAtm, aInfo.applicationInfo,
aInfo.processName, aInfo.applicationInfo.uid, 0 /* userId */,
mock(Object.class) /* owner */, mock(WindowProcessListener.class));
wpc.setThread(mock(IApplicationThread.class));
- doReturn(wpc).when(mService).getProcessController(eq(wpc.mName), eq(wpc.mUid));
+ doReturn(wpc).when(mAtm).getProcessController(eq(wpc.mName), eq(wpc.mUid));
Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
// Null animation indicates to preload.
- mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+ mAtm.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
null /* recentsAnimationRunner */);
Task recentsStack = defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN,
@@ -167,7 +167,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
spyOn(recentsActivity);
// Start when the recents activity exists. It should ensure the configuration.
- mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+ mAtm.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
null /* recentsAnimationRunner */);
verify(recentsActivity).ensureActivityConfiguration(anyInt() /* globalChanges */,
@@ -181,20 +181,20 @@ public class RecentsAnimationTest extends ActivityTestsBase {
TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task recentsStack = defaultTaskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
- ActivityRecord recentActivity = new ActivityBuilder(mService).setComponent(
+ ActivityRecord recentActivity = new ActivityBuilder(mAtm).setComponent(
mRecentsComponent).setCreateTask(true).setStack(recentsStack).build();
WindowProcessController app = recentActivity.app;
recentActivity.app = null;
// Start an activity on top.
- new ActivityBuilder(mService).setCreateTask(true).build().getRootTask().moveToFront(
+ new ActivityBuilder(mAtm).setCreateTask(true).build().getRootTask().moveToFront(
"testRestartRecentsActivity");
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
- doReturn(app).when(mService).getProcessController(eq(recentActivity.processName), anyInt());
- ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
+ doReturn(app).when(mAtm).getProcessController(eq(recentActivity.processName), anyInt());
+ ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doNothing().when(lifecycleManager).scheduleTransaction(any());
startRecentsActivity();
@@ -212,20 +212,20 @@ public class RecentsAnimationTest extends ActivityTestsBase {
// Assume the home activity support recents.
ActivityRecord targetActivity = homeStack.getTopNonFinishingActivity();
if (targetActivity == null) {
- targetActivity = new ActivityBuilder(mService)
+ targetActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setStack(homeStack)
.build();
}
// Put another home activity in home stack.
- ActivityRecord anotherHomeActivity = new ActivityBuilder(mService)
+ ActivityRecord anotherHomeActivity = new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "Home2"))
.setCreateTask(true)
.setStack(homeStack)
.build();
// Start an activity on top so the recents activity can be started.
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setCreateTask(true)
.build()
.getRootTask()
@@ -252,21 +252,21 @@ public class RecentsAnimationTest extends ActivityTestsBase {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
.setCreateTask(true)
.setStack(fullscreenStack)
.build();
Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent)
.setCreateTask(true)
.setStack(recentsStack)
.build();
Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App2"))
.setCreateTask(true)
.setStack(fullscreenStack2)
@@ -293,21 +293,21 @@ public class RecentsAnimationTest extends ActivityTestsBase {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
.setCreateTask(true)
.setStack(fullscreenStack)
.build();
Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent)
.setCreateTask(true)
.setStack(recentsStack)
.build();
Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App2"))
.setCreateTask(true)
.setStack(fullscreenStack2)
@@ -319,7 +319,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
fullscreenStack.removeIfPossible();
// Ensure that the recents animation was NOT canceled
- verify(mService.mWindowManager, times(0)).cancelRecentsAnimation(
+ verify(mAtm.mWindowManager, times(0)).cancelRecentsAnimation(
eq(REORDER_KEEP_IN_PLACE), any());
verify(mRecentsAnimationController, times(0)).setCancelOnNextTransitionStart();
}
@@ -330,7 +330,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
.getDefaultTaskDisplayArea();
Task homeStack = taskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
ACTIVITY_TYPE_HOME);
- ActivityRecord otherUserHomeActivity = new ActivityBuilder(mService)
+ ActivityRecord otherUserHomeActivity = new ActivityBuilder(mAtm)
.setStack(homeStack)
.setCreateTask(true)
.setComponent(new ComponentName(mContext.getPackageName(), "Home2"))
@@ -339,13 +339,13 @@ public class RecentsAnimationTest extends ActivityTestsBase {
Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- new ActivityBuilder(mService)
+ new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
.setCreateTask(true)
.setStack(fullscreenStack)
.build();
- doReturn(TEST_USER_ID).when(mService).getCurrentUserId();
+ doReturn(TEST_USER_ID).when(mAtm).getCurrentUserId();
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
@@ -373,7 +373,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
// The callback is actually RecentsAnimation.
recentsAnimation[0] = invocation.getArgument(2);
return null;
- }).when(mService.mWindowManager).initializeRecentsAnimation(
+ }).when(mAtm.mWindowManager).initializeRecentsAnimation(
anyInt() /* targetActivityType */, any() /* recentsAnimationRunner */,
any() /* callbacks */, anyInt() /* displayId */, any() /* recentTaskIds */,
any() /* targetActivity */);
@@ -381,7 +381,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
Intent recentsIntent = new Intent();
recentsIntent.setComponent(recentsComponent);
- mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+ mAtm.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
mock(IRecentsAnimationRunner.class));
return recentsAnimation[0];
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 74be2c979668..1ec9bd24ad59 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -89,14 +89,14 @@ import java.util.function.Consumer;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class RootActivityContainerTests extends ActivityTestsBase {
+public class RootActivityContainerTests extends WindowTestsBase {
private Task mFullscreenStack;
@Before
public void setUp() throws Exception {
mFullscreenStack = mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- doNothing().when(mService).updateSleepIfNeededLocked();
+ doNothing().when(mAtm).updateSleepIfNeededLocked();
}
/**
@@ -117,11 +117,11 @@ public class RootActivityContainerTests extends ActivityTestsBase {
*/
@Test
public void testReplacingTaskInPinnedStack() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(mFullscreenStack).build();
final Task task = firstActivity.getTask();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task)
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(task)
.setStack(mFullscreenStack).build();
mFullscreenStack.moveToFront("testReplacingTaskInPinnedStack");
@@ -152,11 +152,11 @@ public class RootActivityContainerTests extends ActivityTestsBase {
@Test
public void testMovingBottomMostStackActivityToPinnedStack() {
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(mFullscreenStack).build();
final Task task = firstActivity.getTask();
- final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task)
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(task)
.setStack(mFullscreenStack).build();
mFullscreenStack.moveTaskToBack(task);
@@ -252,7 +252,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
@Test
public void testAwakeFromSleepingWithAppConfiguration() {
final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
- final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
activity.moveFocusableActivityToTop("test");
assertTrue(activity.getStack().isFocusedStackOnDisplay());
ActivityRecordTests.setRotatedScreenOrientationSilently(activity);
@@ -264,13 +264,13 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Assume the activity was shown in different orientation. For example, the top activity is
// landscape and the portrait lockscreen is shown.
activity.setLastReportedConfiguration(
- new MergedConfiguration(mService.getGlobalConfiguration(), rotatedConfig));
+ new MergedConfiguration(mAtm.getGlobalConfiguration(), rotatedConfig));
activity.setState(ActivityState.STOPPED, "sleep");
display.setIsSleeping(true);
doReturn(false).when(display).shouldSleep();
// Allow to resume when awaking.
- setBooted(mService);
+ setBooted(mAtm);
mRootWindowContainer.applySleepTokens(true);
// The display orientation should be changed by the activity so there is no relaunch.
@@ -288,7 +288,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final int originalStackCount = defaultTaskDisplayArea.getStackCount();
final Task stack = defaultTaskDisplayArea.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(stack).build();
assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
@@ -312,16 +312,16 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final int originalStackCount = defaultTaskDisplayArea.getStackCount();
final Task stack = defaultTaskDisplayArea.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(stack).build();
assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent();
- final TaskDisplayArea secondTaskDisplayArea = WindowTestsBase.createTaskDisplayArea(dc,
- mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
+ final TaskDisplayArea secondTaskDisplayArea = WindowTestsBase.createTaskDisplayArea(
+ dc, mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
final Task secondStack = secondTaskDisplayArea.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- new ActivityBuilder(mService).setCreateTask(true).setStack(secondStack)
+ new ActivityBuilder(mAtm).setCreateTask(true).setStack(secondStack)
.setUseProcess(firstActivity.app).build();
assertEquals(1, secondTaskDisplayArea.getStackCount());
@@ -340,7 +340,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
.getDefaultTaskDisplayArea();
final Task stack = defaultTaskDisplayArea.createStack(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(stack).build();
// Created stacks are focusable by default.
@@ -354,7 +354,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task pinnedStack = defaultTaskDisplayArea.createStack(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord pinnedActivity = new ActivityBuilder(mService).setCreateTask(true)
+ final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm).setCreateTask(true)
.setStack(pinnedStack).build();
// We should not be focusable when in pinned mode
@@ -385,7 +385,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
.createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
final Task task = new TaskBuilder(mSupervisor).setStack(primaryStack).build();
- final ActivityRecord r = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord r = new ActivityBuilder(mAtm).setTask(task).build();
// Find a launch stack for the top activity in split-screen primary, while requesting
// split-screen secondary.
@@ -439,7 +439,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task stack = secondDisplay.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
final String reason = "findTaskToMoveToFront";
mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
@@ -459,7 +459,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
taskDisplayArea.positionChildAt(POSITION_BOTTOM, targetStack, false /*includingParents*/);
// Assume the stack is not at the topmost position (e.g. behind always-on-top stacks) but it
@@ -489,7 +489,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
- mService.setBooted(true);
+ mAtm.setBooted(true);
// Trigger resume on all displays
mRootWindowContainer.resumeFocusedStacksTopActivities();
@@ -515,11 +515,11 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task stack = secondDisplay.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
- mService.setBooted(true);
+ mAtm.setBooted(true);
// Trigger resume on all displays
mRootWindowContainer.resumeFocusedStacksTopActivities();
@@ -539,7 +539,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
activity.setState(ActivityState.RESUMED, "test");
// Assume the stack is at the topmost position
@@ -559,7 +559,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
- final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
activity.setState(ActivityState.RESUMED, "test");
taskDisplayArea.positionChildAt(POSITION_BOTTOM, targetStack, false /*includingParents*/);
@@ -584,7 +584,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// Create secondary displays.
final TestDisplayContent secondDisplay =
- new TestDisplayContent.Builder(mService, 1000, 1500)
+ new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setSystemDecorations(true).build();
doReturn(true).when(mRootWindowContainer)
@@ -605,16 +605,16 @@ public class RootActivityContainerTests extends ActivityTestsBase {
@Test
public void testNotStartHomeBeforeBoot() {
final int displayId = 1;
- final boolean isBooting = mService.mAmInternal.isBooting();
- final boolean isBooted = mService.mAmInternal.isBooted();
+ final boolean isBooting = mAtm.mAmInternal.isBooting();
+ final boolean isBooted = mAtm.mAmInternal.isBooted();
try {
- mService.mAmInternal.setBooting(false);
- mService.mAmInternal.setBooted(false);
+ mAtm.mAmInternal.setBooting(false);
+ mAtm.mAmInternal.setBooted(false);
mRootWindowContainer.onDisplayAdded(displayId);
verify(mRootWindowContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
} finally {
- mService.mAmInternal.setBooting(isBooting);
- mService.mAmInternal.setBooted(isBooted);
+ mAtm.mAmInternal.setBooting(isBooting);
+ mAtm.mAmInternal.setBooted(isBooted);
}
}
@@ -626,7 +626,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
final ActivityInfo info = new ActivityInfo();
info.applicationInfo = new ApplicationInfo();
final WindowProcessController app = mock(WindowProcessController.class);
- doReturn(app).when(mService).getProcessController(any(), anyInt());
+ doReturn(app).when(mAtm).getProcessController(any(), anyInt());
// Can not start home if we don't want to start home while home is being instrumented.
doReturn(true).when(app).isInstrumenting();
@@ -653,7 +653,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
public void testStartSecondaryHomeOnDisplayWithUserKeyLocked() {
// Create secondary displays.
final TestDisplayContent secondDisplay =
- new TestDisplayContent.Builder(mService, 1000, 1500)
+ new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setSystemDecorations(true).build();
// Use invalid user id to let StorageManager.isUserKeyUnlocked() return false.
@@ -678,7 +678,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
public void testStartSecondaryHomeOnDisplayWithoutSysDecorations() {
// Create secondary displays.
final TestDisplayContent secondDisplay =
- new TestDisplayContent.Builder(mService, 1000, 1500)
+ new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setSystemDecorations(false).build();
mRootWindowContainer.startHomeOnDisplay(0 /* userId */, "testStartSecondaryHome",
@@ -712,7 +712,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
@Test
public void testResolveSecondaryHomeActivityWhenPrimaryHomeNotSet() {
// Setup: primary home not set.
- final Intent primaryHomeIntent = mService.getHomeIntent();
+ final Intent primaryHomeIntent = mAtm.getHomeIntent();
final ActivityInfo aInfoPrimary = new ActivityInfo();
aInfoPrimary.name = ResolverActivity.class.getName();
doReturn(aInfoPrimary).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
@@ -740,7 +740,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
// SetUp: set secondary home and force it.
mockResolveHomeActivity(false /* primaryHome */, true /* forceSystemProvided */);
final Intent secondaryHomeIntent =
- mService.getSecondaryHomeIntent(null /* preferredPackage */);
+ mAtm.getSecondaryHomeIntent(null /* preferredPackage */);
final List<ResolveInfo> resolutions = new ArrayList<>();
final ResolveInfo resolveInfo = new ResolveInfo();
final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false /* primaryHome*/);
@@ -855,11 +855,11 @@ public class RootActivityContainerTests extends ActivityTestsBase {
public void testGetLaunchStackWithRealCallerId() {
// Create a non-system owned virtual display.
final TestDisplayContent secondaryDisplay =
- new TestDisplayContent.Builder(mService, 1000, 1500)
+ new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setType(TYPE_VIRTUAL).setOwnerUid(100).build();
// Create an activity with specify the original launch pid / uid.
- final ActivityRecord r = new ActivityBuilder(mService).setLaunchedFromPid(200)
+ final ActivityRecord r = new ActivityBuilder(mAtm).setLaunchedFromPid(200)
.setLaunchedFromUid(200).build();
// Simulate ActivityStarter to find a launch stack for requesting the activity to launch
@@ -882,12 +882,11 @@ public class RootActivityContainerTests extends ActivityTestsBase {
@Test
public void testGetValidLaunchStackOnDisplayWithCandidateRootTask() {
// Create a root task with an activity on secondary display.
- final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mService, 300,
+ final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mAtm, 300,
600).build();
- final Task task = new ActivityTestsBase.StackBuilder(mRootWindowContainer).setDisplay(
- secondaryDisplay).build();
- final ActivityRecord activity = new ActivityTestsBase.ActivityBuilder(mService)
- .setTask(task).build();
+ final Task task = new StackBuilder(mRootWindowContainer)
+ .setDisplay(secondaryDisplay).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
// Make sure the root task is valid and can be reused on default display.
final Task stack = mRootWindowContainer.getValidLaunchStackInTaskDisplayArea(
@@ -923,7 +922,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
DisplayContent.POSITION_TOP);
final Task stack = secondDisplay.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mService).setStack(stack).build();
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setStack(stack).build();
spyOn(activity);
spyOn(stack);
@@ -946,7 +945,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
ActivityInfo targetActivityInfo = getFakeHomeActivityInfo(primaryHome);
Intent targetIntent;
if (primaryHome) {
- targetIntent = mService.getHomeIntent();
+ targetIntent = mAtm.getHomeIntent();
} else {
Resources resources = mContext.getResources();
spyOn(resources);
@@ -954,7 +953,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
com.android.internal.R.string.config_secondaryHomePackage);
doReturn(forceSystemProvided).when(resources).getBoolean(
com.android.internal.R.bool.config_useSystemProvidedLauncherForSecondary);
- targetIntent = mService.getSecondaryHomeIntent(null /* preferredPackage */);
+ targetIntent = mAtm.getSecondaryHomeIntent(null /* preferredPackage */);
}
doReturn(targetActivityInfo).when(mRootWindowContainer).resolveHomeActivity(anyInt(),
refEq(targetIntent));
@@ -965,7 +964,7 @@ public class RootActivityContainerTests extends ActivityTestsBase {
* activity info for test cases.
*/
private void mockResolveSecondaryHomeActivity() {
- final Intent secondaryHomeIntent = mService
+ final Intent secondaryHomeIntent = mAtm
.getSecondaryHomeIntent(null /* preferredPackage */);
final ActivityInfo aInfoSecondary = getFakeHomeActivityInfo(false);
doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootWindowContainer)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 2e4c9ea747c5..72899e726b6e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -133,10 +133,10 @@ public class RootWindowContainerTests extends WindowTestsBase {
@Test
public void testFindActivityByTargetComponent() {
final ComponentName aliasComponent = ComponentName.createRelative(
- ActivityTestsBase.DEFAULT_COMPONENT_PACKAGE_NAME, ".AliasActivity");
+ DEFAULT_COMPONENT_PACKAGE_NAME, ".AliasActivity");
final ComponentName targetComponent = ComponentName.createRelative(
aliasComponent.getPackageName(), ".TargetActivity");
- final ActivityRecord activity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ final ActivityRecord activity = new ActivityBuilder(mWm.mAtmService)
.setComponent(aliasComponent)
.setTargetActivity(targetComponent.getClassName())
.setLaunchMode(ActivityInfo.LAUNCH_SINGLE_INSTANCE)
@@ -174,24 +174,29 @@ public class RootWindowContainerTests extends WindowTestsBase {
@Test
public void testForceStopPackage() {
- final Task task = new ActivityTestsBase.StackBuilder(mWm.mRoot).build();
- final ActivityRecord activity1 = task.getTopMostActivity();
- final ActivityRecord activity2 =
- new ActivityTestsBase.ActivityBuilder(mWm.mAtmService).setStack(task).build();
- final WindowProcessController wpc = activity1.app;
+ final Task task = new StackBuilder(mWm.mRoot).build();
+ final ActivityRecord activity = task.getTopMostActivity();
+ final WindowProcessController wpc = activity.app;
+ final ActivityRecord[] activities = {
+ activity,
+ new ActivityBuilder(mWm.mAtmService).setStack(task).setUseProcess(wpc).build(),
+ new ActivityBuilder(mWm.mAtmService).setStack(task).setUseProcess(wpc).build()
+ };
+ activities[0].detachFromProcess();
+ activities[1].finishing = true;
+ activities[1].destroyImmediately(true /* removeFromApp */, "test");
spyOn(wpc);
- activity1.app = null;
- activity2.setProcess(wpc);
doReturn(true).when(wpc).isRemoved();
mWm.mAtmService.mInternal.onForceStopPackage(wpc.mInfo.packageName, true /* doit */,
false /* evenPersistent */, wpc.mUserId);
// The activity without process should be removed.
- assertEquals(1, task.getChildCount());
+ assertEquals(2, task.getChildCount());
- mWm.mRoot.handleAppDied(wpc);
- // The activity with process should be removed because WindowProcessController#isRemoved.
+ wpc.handleAppDied();
+ // The activities with process should be removed because WindowProcessController#isRemoved.
assertFalse(task.hasChild());
+ assertFalse(wpc.hasActivities());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index e51a133d5cce..341509310e26 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -42,7 +42,7 @@ import java.util.ArrayList;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class RunningTasksTest extends ActivityTestsBase {
+public class RunningTasksTest extends WindowTestsBase {
private static final ArraySet<Integer> PROFILE_IDS = new ArraySet<>();
@@ -57,7 +57,7 @@ public class RunningTasksTest extends ActivityTestsBase {
public void testCollectTasksByLastActiveTime() {
// Create a number of stacks with tasks (of incrementing active time)
final ArrayList<DisplayContent> displays = new ArrayList<>();
- final DisplayContent display = new TestDisplayContent.Builder(mService, 1000, 2500).build();
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
displays.add(display);
final int numStacks = 2;
@@ -101,7 +101,7 @@ public class RunningTasksTest extends ActivityTestsBase {
@Test
public void testTaskInfo_expectNoExtras() {
- final DisplayContent display = new TestDisplayContent.Builder(mService, 1000, 2500).build();
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
final int numTasks = 10;
for (int i = 0; i < numTasks; i++) {
final Task stack = new StackBuilder(mRootWindowContainer)
@@ -132,13 +132,13 @@ public class RunningTasksTest extends ActivityTestsBase {
*/
private Task createTask(Task stack, String className, int taskId,
int lastActiveTime, Bundle extras) {
- final Task task = new TaskBuilder(mService.mStackSupervisor)
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor)
.setComponent(new ComponentName(mContext.getPackageName(), className))
.setTaskId(taskId)
.setStack(stack)
.build();
task.lastActiveTime = lastActiveTime;
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(task)
.setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity"))
.setIntentExtras(extras)
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 250cf09e8547..0e1d4dc4aa0d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -64,7 +64,7 @@ import java.util.ArrayList;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class SizeCompatTests extends ActivityTestsBase {
+public class SizeCompatTests extends WindowTestsBase {
private Task mStack;
private Task mTask;
private ActivityRecord mActivity;
@@ -76,7 +76,7 @@ public class SizeCompatTests extends ActivityTestsBase {
}
private void setUpDisplaySizeWithApp(int dw, int dh) {
- final TestDisplayContent.Builder builder = new TestDisplayContent.Builder(mService, dw, dh);
+ final TestDisplayContent.Builder builder = new TestDisplayContent.Builder(mAtm, dw, dh);
setUpApp(builder.build());
}
@@ -92,7 +92,7 @@ public class SizeCompatTests extends ActivityTestsBase {
final Rect originalOverrideBounds = new Rect(mActivity.getBounds());
resizeDisplay(mStack.getDisplay(), 600, 1200);
// The visible activity should recompute configuration according to the last parent bounds.
- mService.restartActivityProcessIfVisible(mActivity.appToken);
+ mAtm.restartActivityProcessIfVisible(mActivity.appToken);
assertEquals(Task.ActivityState.RESTARTING_PROCESS, mActivity.getState());
assertNotEquals(originalOverrideBounds, mActivity.getBounds());
@@ -102,7 +102,7 @@ public class SizeCompatTests extends ActivityTestsBase {
public void testKeepBoundsWhenChangingFromFreeformToFullscreen() {
removeGlobalMinSizeRestriction();
// create freeform display and a freeform app
- DisplayContent display = new TestDisplayContent.Builder(mService, 2000, 1000)
+ DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000)
.setCanRotate(false)
.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build();
setUpApp(display);
@@ -135,7 +135,7 @@ public class SizeCompatTests extends ActivityTestsBase {
@Test
public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() {
final int notchHeight = 100;
- setUpApp(new TestDisplayContent.Builder(mService, 600, 800).setNotch(notchHeight).build());
+ setUpApp(new TestDisplayContent.Builder(mAtm, 600, 800).setNotch(notchHeight).build());
// Rotation is ignored so because the display size is close to square (700/600<1.333).
assertTrue(mActivity.mDisplayContent.ignoreRotationForApps());
@@ -186,10 +186,10 @@ public class SizeCompatTests extends ActivityTestsBase {
// Make a new less-tall display with lower density
final DisplayContent newDisplay =
- new TestDisplayContent.Builder(mService, 1000, 2000)
+ new TestDisplayContent.Builder(mAtm, 1000, 2000)
.setDensityDpi(200).build();
- mActivity = new ActivityBuilder(mService)
+ mActivity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setResizeMode(RESIZE_MODE_UNRESIZEABLE)
.setMaxAspectRatio(1.5f)
@@ -262,7 +262,7 @@ public class SizeCompatTests extends ActivityTestsBase {
@Test
public void testAspectRatioMatchParentBoundsAndImeAttachable() {
- setUpApp(new TestDisplayContent.Builder(mService, 1000, 2000)
+ setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2000)
.setSystemDecorations(true).build());
prepareUnresizable(2f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
assertFitted();
@@ -293,7 +293,7 @@ public class SizeCompatTests extends ActivityTestsBase {
final int origHeight = configBounds.height();
final int notchHeight = 100;
- final DisplayContent newDisplay = new TestDisplayContent.Builder(mService, 2000, 1000)
+ final DisplayContent newDisplay = new TestDisplayContent.Builder(mAtm, 2000, 1000)
.setCanRotate(false).setNotch(notchHeight).build();
// Move the non-resizable activity to the new display.
@@ -327,7 +327,7 @@ public class SizeCompatTests extends ActivityTestsBase {
public void testFixedOrientRotateCutoutDisplay() {
// Create a display with a notch/cutout
final int notchHeight = 60;
- setUpApp(new TestDisplayContent.Builder(mService, 1000, 2500)
+ setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500)
.setNotch(notchHeight).build());
// Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460].
prepareUnresizable(1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
@@ -430,14 +430,14 @@ public class SizeCompatTests extends ActivityTestsBase {
// Change display density
display.mBaseDisplayDensity = (int) (0.7f * display.mBaseDisplayDensity);
display.computeScreenConfiguration(rotatedConfig);
- mService.mAmInternal = mock(ActivityManagerInternal.class);
+ mAtm.mAmInternal = mock(ActivityManagerInternal.class);
display.onRequestedOverrideConfigurationChanged(rotatedConfig);
// The override configuration should be reset and the activity's process will be killed.
assertFitted();
verify(mActivity).restartProcessIfVisible();
- waitHandlerIdle(mService.mH);
- verify(mService.mAmInternal).killProcess(
+ waitHandlerIdle(mAtm.mH);
+ verify(mAtm.mAmInternal).killProcess(
eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString());
}
@@ -454,7 +454,7 @@ public class SizeCompatTests extends ActivityTestsBase {
assertFitted();
final ArrayList<IBinder> compatTokens = new ArrayList<>();
- mService.getTaskChangeNotificationController().registerTaskStackListener(
+ mAtm.getTaskChangeNotificationController().registerTaskStackListener(
new TaskStackListener() {
@Override
public void onSizeCompatModeActivityChanged(int displayId,
@@ -492,7 +492,7 @@ public class SizeCompatTests extends ActivityTestsBase {
mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
@@ -516,7 +516,7 @@ public class SizeCompatTests extends ActivityTestsBase {
final int dw = 1000;
final int dh = 2500;
final int notchHeight = 200;
- setUpApp(new TestDisplayContent.Builder(mService, dw, dh).setNotch(notchHeight).build());
+ setUpApp(new TestDisplayContent.Builder(mAtm, dw, dh).setNotch(notchHeight).build());
addStatusBar(mActivity.mDisplayContent);
mActivity.setVisible(false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 27a8fc3c5943..3492556b3682 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -219,8 +219,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
final Task rootHomeTask = defaultTaskDisplayArea.getRootHomeTask();
rootHomeTask.mResizeMode = RESIZE_MODE_UNRESIZEABLE;
- final Task primarySplitTask =
- new ActivityTestsBase.StackBuilder(rootWindowContainer)
+ final Task primarySplitTask = new StackBuilder(rootWindowContainer)
.setTaskDisplayArea(defaultTaskDisplayArea)
.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
.setActivityType(ACTIVITY_TYPE_STANDARD)
@@ -234,7 +233,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
ActivityRecord homeActivity = rootHomeTask.getTopNonFinishingActivity();
if (homeActivity == null) {
- homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ homeActivity = new ActivityBuilder(mWm.mAtmService)
.setStack(rootHomeTask).setCreateTask(true).build();
}
homeActivity.setVisible(false);
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 a048526bb068..42de5e6b429d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -67,7 +67,7 @@ import java.util.Locale;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
+public class TaskLaunchParamsModifierTests extends WindowTestsBase {
private static final Rect DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
/* right */ 1920, /* bottom */ 1080);
private static final Rect DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100,
@@ -82,7 +82,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
@Before
public void setUp() throws Exception {
- mActivity = new ActivityBuilder(mService).build();
+ mActivity = new ActivityBuilder(mAtm).build();
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
mActivity.info.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
@@ -449,7 +449,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
@Test
public void testForceMaximizesUnresizeableApp() {
- mService.mSizeCompatFreeform = false;
+ mAtm.mSizeCompatFreeform = false;
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
@@ -472,7 +472,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
@Test
public void testLaunchesAppInWindowOnFreeformDisplay() {
- mService.mSizeCompatFreeform = true;
+ mAtm.mSizeCompatFreeform = true;
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
@@ -1318,18 +1318,18 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
@Test
public void testNoMultiDisplaySupports() {
- final boolean orgValue = mService.mSupportsMultiDisplay;
+ final boolean orgValue = mAtm.mSupportsMultiDisplay;
final TestDisplayContent display = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
mCurrent.mPreferredTaskDisplayArea = display.getDefaultTaskDisplayArea();
try {
- mService.mSupportsMultiDisplay = false;
+ mAtm.mSupportsMultiDisplay = false;
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(),
mResult.mPreferredTaskDisplayArea);
} finally {
- mService.mSupportsMultiDisplay = orgValue;
+ mAtm.mSupportsMultiDisplay = orgValue;
}
}
@@ -1351,7 +1351,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
private ActivityRecord createSourceActivity(TestDisplayContent display) {
final Task stack = display.getDefaultTaskDisplayArea()
.createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
- return new ActivityBuilder(mService).setStack(stack).setCreateTask(true).build();
+ return new ActivityBuilder(mAtm).setStack(stack).setCreateTask(true).build();
}
private void addFreeformTaskTo(TestDisplayContent display, Rect bounds) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
index 0db3f94d1fc3..27cae2fc1a4c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
@@ -77,7 +77,7 @@ public class TaskPositionerTests extends WindowTestsBase {
removeGlobalMinSizeRestriction();
final Task stack = createTaskStackOnDisplay(mDisplayContent);
- final ActivityRecord activity = new ActivityTestsBase.ActivityBuilder(stack.mAtmService)
+ final ActivityRecord activity = new ActivityBuilder(stack.mAtmService)
.setStack(stack)
// In real case, there is no additional level for freeform mode.
.setCreateTask(false)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index bf76c8ee5f0a..fc54e1de888f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -95,7 +95,7 @@ import java.io.Reader;
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class TaskRecordTests extends ActivityTestsBase {
+public class TaskRecordTests extends WindowTestsBase {
private static final String TASK_TAG = "task";
@@ -172,7 +172,7 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testFitWithinBounds() {
final Rect parentBounds = new Rect(10, 10, 200, 200);
- TaskDisplayArea taskDisplayArea = mService.mRootWindowContainer.getDefaultTaskDisplayArea();
+ TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
@@ -210,7 +210,7 @@ public class TaskRecordTests extends ActivityTestsBase {
/** Tests that the task bounds adjust properly to changes between FULLSCREEN and FREEFORM */
@Test
public void testBoundsOnModeChangeFreeformToFullscreen() {
- DisplayContent display = mService.mRootWindowContainer.getDefaultDisplay();
+ DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
Task stack = new StackBuilder(mRootWindowContainer).setDisplay(display)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
Task task = stack.getBottomMostTask();
@@ -243,7 +243,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testFullscreenBoundsForcedOrientation() {
final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
final Rect fullScreenBoundsPort = new Rect(0, 0, 1080, 1920);
- final DisplayContent display = new TestDisplayContent.Builder(mService,
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm,
fullScreenBounds.width(), fullScreenBounds.height()).setCanRotate(false).build();
assertTrue(mRootWindowContainer.getDisplayContent(display.mDisplayId) != null);
// Fix the display orientation to landscape which is the natural rotation (0) for the test
@@ -267,7 +267,7 @@ public class TaskRecordTests extends ActivityTestsBase {
assertEquals(fullScreenBounds.height(), task.getBounds().height());
// Top activity gets used
- ActivityRecord top = new ActivityBuilder(mService).setTask(task).setStack(stack).build();
+ ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).setStack(stack).build();
assertEquals(top, task.getTopNonFinishingActivity());
top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height());
@@ -307,7 +307,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testIgnoresForcedOrientationWhenParentHandles() {
final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
DisplayContent display = new TestDisplayContent.Builder(
- mService, fullScreenBounds.width(), fullScreenBounds.height()).build();
+ mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
display.getRequestedOverrideConfiguration().orientation =
Configuration.ORIENTATION_LANDSCAPE;
@@ -339,7 +339,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testComputeConfigResourceOverrides() {
final Rect fullScreenBounds = new Rect(0, 0, 1080, 1920);
TestDisplayContent display = new TestDisplayContent.Builder(
- mService, fullScreenBounds.width(), fullScreenBounds.height()).build();
+ mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
final Configuration inOutConfig = new Configuration();
final Configuration parentConfig = new Configuration();
@@ -438,11 +438,11 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
- TaskDisplayArea taskDisplayArea = mService.mRootWindowContainer.getDefaultTaskDisplayArea();
+ TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
DisplayInfo displayInfo = new DisplayInfo();
- mService.mContext.getDisplay().getDisplayInfo(displayInfo);
+ mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
final int displayHeight = displayInfo.logicalHeight;
final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
final Configuration inOutConfig = new Configuration();
@@ -514,23 +514,23 @@ public class TaskRecordTests extends ActivityTestsBase {
info.packageName = DEFAULT_COMPONENT_PACKAGE_NAME;
info.targetActivity = targetClassName;
- final Task task = new Task(mService, 1 /* taskId */, info, intent,
+ final Task task = new Task(mAtm, 1 /* taskId */, info, intent,
null /* voiceSession */, null /* voiceInteractor */, null /* taskDescriptor */,
null /*stack*/);
assertEquals("The alias activity component should be saved in task intent.", aliasClassName,
task.intent.getComponent().getClassName());
- ActivityRecord aliasActivity = new ActivityBuilder(mService).setComponent(
+ ActivityRecord aliasActivity = new ActivityBuilder(mAtm).setComponent(
aliasComponent).setTargetActivity(targetClassName).build();
assertEquals("Should be the same intent filter.", true,
task.isSameIntentFilter(aliasActivity));
- ActivityRecord targetActivity = new ActivityBuilder(mService).setComponent(
+ ActivityRecord targetActivity = new ActivityBuilder(mAtm).setComponent(
targetComponent).build();
assertEquals("Should be the same intent filter.", true,
task.isSameIntentFilter(targetActivity));
- ActivityRecord defaultActivity = new ActivityBuilder(mService).build();
+ ActivityRecord defaultActivity = new ActivityBuilder(mAtm).build();
assertEquals("Should not be the same intent filter.", false,
task.isSameIntentFilter(defaultActivity));
}
@@ -540,7 +540,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testFindRootIndex() {
final Task task = getTestTask();
// Add an extra activity on top of the root one
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
assertEquals("The root activity in the task must be reported.", task.getChildAt(0),
task.getRootActivity(
@@ -557,9 +557,9 @@ public class TaskRecordTests extends ActivityTestsBase {
// Add extra two activities and mark the two on the bottom as finishing.
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.finishing = true;
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.finishing = true;
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
assertEquals("The first non-finishing activity in the task must be reported.",
task.getChildAt(2), task.getRootActivity(
@@ -574,7 +574,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testFindRootIndex_effectiveRoot() {
final Task task = getTestTask();
// Add an extra activity on top of the root one
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
assertEquals("The root activity in the task must be reported.",
task.getChildAt(0), task.getRootActivity(
@@ -592,9 +592,9 @@ public class TaskRecordTests extends ActivityTestsBase {
// one above as finishing.
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.finishing = true;
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
assertEquals("The first non-finishing activity and non-relinquishing task identity "
+ "must be reported.", task.getChildAt(2), task.getRootActivity(
@@ -626,7 +626,7 @@ public class TaskRecordTests extends ActivityTestsBase {
// Set relinquishTaskIdentity for all activities in the task
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
assertEquals("The topmost activity in the task must be reported.",
@@ -639,7 +639,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testGetRootActivity() {
final Task task = getTestTask();
// Add an extra activity on top of the root one
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
assertEquals("The root activity in the task must be reported.",
task.getBottomMostActivity(), task.getRootActivity());
@@ -652,7 +652,7 @@ public class TaskRecordTests extends ActivityTestsBase {
public void testGetRootActivity_finishing() {
final Task task = getTestTask();
// Add an extra activity on top of the root one
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
// Mark the root as finishing
task.getBottomMostActivity().finishing = true;
@@ -670,7 +670,7 @@ public class TaskRecordTests extends ActivityTestsBase {
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
// Add an extra activity on top of the root one.
- new ActivityBuilder(mService).setTask(task).build();
+ new ActivityBuilder(mAtm).setTask(task).build();
assertEquals("The root activity in the task must be reported.",
task.getBottomMostActivity(), task.getRootActivity());
@@ -687,7 +687,7 @@ public class TaskRecordTests extends ActivityTestsBase {
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.finishing = true;
// Add an extra activity on top of the root one and mark it as finishing
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.finishing = true;
assertNull("No activity must be reported if all are finishing", task.getRootActivity());
@@ -703,7 +703,7 @@ public class TaskRecordTests extends ActivityTestsBase {
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.finishing = true;
// Add an extra activity on top of the root one.
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
assertFalse("Finishing activity must not be the root of task", activity0.isRootOfTask());
assertTrue("Non-finishing activity must be the root of task", activity1.isRootOfTask());
@@ -720,7 +720,7 @@ public class TaskRecordTests extends ActivityTestsBase {
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.finishing = true;
// Add an extra activity on top of the root one and mark it as finishing
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.finishing = true;
assertTrue("Bottom activity must be the root of task", activity0.isRootOfTask());
@@ -756,9 +756,9 @@ public class TaskRecordTests extends ActivityTestsBase {
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.finishing = true;
// Add an extra activity on top - this will be the new root
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
// Add one more on top
- final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
@@ -779,9 +779,9 @@ public class TaskRecordTests extends ActivityTestsBase {
final ActivityRecord activity0 = task.getBottomMostActivity();
activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
// Add an extra activity on top - this will be the new root
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
// Add one more on top
- final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
@@ -803,11 +803,11 @@ public class TaskRecordTests extends ActivityTestsBase {
activity0.finishing = true;
// Add an extra activity on top of the root one and make it relinquish task identity
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
// Add one more activity on top
- final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
@@ -843,7 +843,7 @@ public class TaskRecordTests extends ActivityTestsBase {
// Mark the bottom-most activity as finishing.
activity0.finishing = true;
// Add an extra activity on top of the root one
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
spyOn(task);
task.updateEffectiveIntent();
@@ -863,7 +863,7 @@ public class TaskRecordTests extends ActivityTestsBase {
// Mark the bottom-most activity as finishing.
activity0.finishing = true;
// Add an extra activity on top of the root one and make it relinquish task identity
- final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
activity1.finishing = true;
// Task must still update the intent using the root activity (preserving legacy behavior).
@@ -874,7 +874,7 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testSaveLaunchingStateWhenConfigurationChanged() {
- LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister;
+ LaunchParamsPersister persister = mAtm.mStackSupervisor.mLaunchParamsPersister;
spyOn(persister);
final Task task = getTestTask();
@@ -890,7 +890,7 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testSaveLaunchingStateWhenClearingParent() {
- LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister;
+ LaunchParamsPersister persister = mAtm.mStackSupervisor.mLaunchParamsPersister;
spyOn(persister);
final Task task = getTestTask();
@@ -915,7 +915,7 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testNotSaveLaunchingStateNonFreeformDisplay() {
- LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister;
+ LaunchParamsPersister persister = mAtm.mStackSupervisor.mLaunchParamsPersister;
spyOn(persister);
final Task task = getTestTask();
@@ -930,7 +930,7 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testNotSaveLaunchingStateWhenNotFullscreenOrFreeformWindow() {
- LaunchParamsPersister persister = mService.mStackSupervisor.mLaunchParamsPersister;
+ LaunchParamsPersister persister = mAtm.mStackSupervisor.mLaunchParamsPersister;
spyOn(persister);
final Task task = getTestTask();
@@ -983,7 +983,7 @@ public class TaskRecordTests extends ActivityTestsBase {
private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
Rect expectedConfigBounds) {
- TaskDisplayArea taskDisplayArea = mService.mRootWindowContainer.getDefaultTaskDisplayArea();
+ TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task stack = taskDisplayArea.createStack(windowingMode, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
@@ -1019,12 +1019,12 @@ public class TaskRecordTests extends ActivityTestsBase {
parser.setInput(reader);
assertEquals(XmlPullParser.START_TAG, parser.next());
assertEquals(TASK_TAG, parser.getName());
- return Task.restoreFromXml(parser, mService.mStackSupervisor);
+ return Task.restoreFromXml(parser, mAtm.mStackSupervisor);
}
}
private Task createTask(int taskId) {
- return new Task(mService, taskId, new Intent(), null, null, null,
+ return new Task(mAtm, taskId, new Intent(), null, null, null,
ActivityBuilder.getDefaultComponent(), null, false, false, false, 0, 10050, null,
0, false, null, 0, 0, 0, 0, null, null, 0, false, false, false, 0,
0, null /*ActivityInfo*/, null /*_voiceSession*/, null /*_voiceInteractor*/,
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index e8a4e90b1aa1..75ed928b08a0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -79,6 +79,16 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
}
@Test
+ public void testRemoveFinishingInvisibleActivityFromUnknown() {
+ final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(mDisplayContent);
+ mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
+ activity.finishing = true;
+ activity.mVisibleRequested = true;
+ activity.setVisibility(false, false);
+ assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
+ }
+
+ @Test
public void testAppRemoved() {
final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(mDisplayContent);
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 573e37a2d6b3..ed9e2707ae39 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -295,7 +295,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
}
private WindowState createWallpaperTargetWindow(DisplayContent dc) {
- final ActivityRecord homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
.setStack(dc.getDefaultTaskDisplayArea().getRootHomeTask())
.setCreateTask(true)
.build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 3ebc28886377..8ac44f2afcfd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -830,7 +830,7 @@ public class WindowContainerTests extends WindowTestsBase {
final DisplayContent displayContent = createNewDisplay();
// Do not reparent activity to default display when removing the display.
doReturn(true).when(displayContent).shouldDestroyContentOnRemove();
- final ActivityRecord r = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final ActivityRecord r = new StackBuilder(mWm.mRoot)
.setDisplay(displayContent).build().getTopMostActivity();
// Add a window and make the activity animating so the removal of activity is deferred.
createWindow(null, TYPE_BASE_APPLICATION, r, "win");
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 800a5d42ce09..8cfa4f00c8b6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -321,7 +321,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Test
public void testTaskTransaction() {
removeGlobalMinSizeRestriction();
- final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final Task stack = new StackBuilder(mWm.mRoot)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask();
testTransaction(task);
@@ -330,7 +330,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Test
public void testStackTransaction() {
removeGlobalMinSizeRestriction();
- final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final Task stack = new StackBuilder(mWm.mRoot)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
StackInfo info =
mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
@@ -355,7 +355,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Test
public void testSetWindowingMode() {
- final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final Task stack = new StackBuilder(mWm.mRoot)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
testSetWindowingMode(stack);
@@ -389,7 +389,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Test
public void testContainerFocusableChanges() {
removeGlobalMinSizeRestriction();
- final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final Task stack = new StackBuilder(mWm.mRoot)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction();
@@ -405,7 +405,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Test
public void testContainerHiddenChanges() {
removeGlobalMinSizeRestriction();
- final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final Task stack = new StackBuilder(mWm.mRoot)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
WindowContainerTransaction t = new WindowContainerTransaction();
assertTrue(stack.shouldBeVisible(null));
@@ -420,7 +420,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Test
public void testOverrideConfigSize() {
removeGlobalMinSizeRestriction();
- final Task stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+ final Task stack = new StackBuilder(mWm.mRoot)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerMapTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerMapTests.java
index cb7bff3a4f15..c2ee0798fd07 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerMapTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerMapTests.java
@@ -31,6 +31,7 @@ import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link WindowProcessControllerMap} class.
@@ -40,7 +41,8 @@ import org.junit.Test;
*/
@SmallTest
@Presubmit
-public class WindowProcessControllerMapTests extends ActivityTestsBase {
+@RunWith(WindowTestRunner.class)
+public class WindowProcessControllerMapTests extends WindowTestsBase {
private static final int FAKE_UID1 = 666;
private static final int FAKE_UID2 = 667;
@@ -60,23 +62,23 @@ public class WindowProcessControllerMapTests extends ActivityTestsBase {
public void setUp() throws Exception {
mProcessMap = new WindowProcessControllerMap();
pid1uid1 = new WindowProcessController(
- mService, mService.mContext.getApplicationInfo(), "fakepid1fakeuid1", FAKE_UID1,
+ mAtm, mAtm.mContext.getApplicationInfo(), "fakepid1fakeuid1", FAKE_UID1,
UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
pid1uid1.setPid(FAKE_PID1);
pid1uid2 = new WindowProcessController(
- mService, mService.mContext.getApplicationInfo(), "fakepid1fakeuid2", FAKE_UID2,
+ mAtm, mAtm.mContext.getApplicationInfo(), "fakepid1fakeuid2", FAKE_UID2,
UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
pid1uid2.setPid(FAKE_PID1);
pid2uid1 = new WindowProcessController(
- mService, mService.mContext.getApplicationInfo(), "fakepid2fakeuid1", FAKE_UID1,
+ mAtm, mAtm.mContext.getApplicationInfo(), "fakepid2fakeuid1", FAKE_UID1,
UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
pid2uid1.setPid(FAKE_PID2);
pid3uid1 = new WindowProcessController(
- mService, mService.mContext.getApplicationInfo(), "fakepid3fakeuid1", FAKE_UID1,
+ mAtm, mAtm.mContext.getApplicationInfo(), "fakepid3fakeuid1", FAKE_UID1,
UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
pid3uid1.setPid(FAKE_PID3);
pid4uid2 = new WindowProcessController(
- mService, mService.mContext.getApplicationInfo(), "fakepid4fakeuid2", FAKE_UID2,
+ mAtm, mAtm.mContext.getApplicationInfo(), "fakepid4fakeuid2", FAKE_UID2,
UserHandle.getUserId(12345), mock(Object.class), mock(WindowProcessListener.class));
pid4uid2.setPid(FAKE_PID4);
}
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 cdf8eb4faf1d..2f736555ae1b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -50,7 +50,7 @@ import org.mockito.Mockito;
*/
@Presubmit
@RunWith(WindowTestRunner.class)
-public class WindowProcessControllerTests extends ActivityTestsBase {
+public class WindowProcessControllerTests extends WindowTestsBase {
WindowProcessController mWpc;
WindowProcessListener mMockListener;
@@ -62,7 +62,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
ApplicationInfo info = mock(ApplicationInfo.class);
info.packageName = "test.package.name";
mWpc = new WindowProcessController(
- mService, info, null, 0, -1, null, mMockListener);
+ mAtm, info, null, 0, -1, null, mMockListener);
mWpc.setThread(mock(IApplicationThread.class));
}
@@ -108,7 +108,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
public void testSetRunningRecentsAnimation() {
mWpc.setRunningRecentsAnimation(true);
mWpc.setRunningRecentsAnimation(false);
- waitHandlerIdle(mService.mH);
+ waitHandlerIdle(mAtm.mH);
InOrder orderVerifier = Mockito.inOrder(mMockListener);
orderVerifier.verify(mMockListener).setRunningRemoteAnimation(eq(true));
@@ -119,7 +119,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
public void testSetRunningRemoteAnimation() {
mWpc.setRunningRemoteAnimation(true);
mWpc.setRunningRemoteAnimation(false);
- waitHandlerIdle(mService.mH);
+ waitHandlerIdle(mAtm.mH);
InOrder orderVerifier = Mockito.inOrder(mMockListener);
orderVerifier.verify(mMockListener).setRunningRemoteAnimation(eq(true));
@@ -133,7 +133,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
mWpc.setRunningRecentsAnimation(false);
mWpc.setRunningRemoteAnimation(false);
- waitHandlerIdle(mService.mH);
+ waitHandlerIdle(mAtm.mH);
InOrder orderVerifier = Mockito.inOrder(mMockListener);
orderVerifier.verify(mMockListener, times(3)).setRunningRemoteAnimation(eq(true));
@@ -147,12 +147,12 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
assertEquals(INVALID_DISPLAY, mWpc.getDisplayId());
// Register to a new display as a listener.
- final DisplayContent display = new TestDisplayContent.Builder(mService, 2000, 1000)
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000)
.setDensityDpi(300).setPosition(DisplayContent.POSITION_TOP).build();
mWpc.registerDisplayConfigurationListener(display);
assertEquals(display.mDisplayId, mWpc.getDisplayId());
- final Configuration expectedConfig = mService.mRootWindowContainer.getConfiguration();
+ final Configuration expectedConfig = mAtm.mRootWindowContainer.getConfiguration();
expectedConfig.updateFrom(display.getConfiguration());
assertEquals(expectedConfig, mWpc.getConfiguration());
}
@@ -184,15 +184,15 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
@Test
public void testActivityNotOverridingSystemUiProcessConfig() {
- final ComponentName systemUiServiceComponent = mService.getSysUiServiceComponentLocked();
+ final ComponentName systemUiServiceComponent = mAtm.getSysUiServiceComponentLocked();
ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
applicationInfo.packageName = systemUiServiceComponent.getPackageName();
WindowProcessController wpc = new WindowProcessController(
- mService, applicationInfo, null, 0, -1, null, mMockListener);
+ mAtm, applicationInfo, null, 0, -1, null, mMockListener);
wpc.setThread(mock(IApplicationThread.class));
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setUseProcess(wpc)
.build();
@@ -209,7 +209,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
// Notify WPC that this process has started an IME service.
mWpc.onServiceStarted(serviceInfo);
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setUseProcess(mWpc)
.build();
@@ -226,7 +226,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
// Notify WPC that this process has started an ally service.
mWpc.onServiceStarted(serviceInfo);
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setUseProcess(mWpc)
.build();
@@ -243,7 +243,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
// Notify WPC that this process has started an voice interaction service.
mWpc.onServiceStarted(serviceInfo);
- final ActivityRecord activity = new ActivityBuilder(mService)
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.setUseProcess(mWpc)
.build();
@@ -254,7 +254,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
}
private TestDisplayContent createTestDisplayContentInContainer() {
- return new TestDisplayContent.Builder(mService, 1000, 1500).build();
+ return new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
}
private static void invertOrientation(Configuration config) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index 2502932c5421..0180d87290a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -25,7 +25,7 @@ import android.os.IBinder;
import android.view.IWindow;
import android.view.WindowManager;
-import com.android.server.wm.ActivityTestsBase.ActivityBuilder;
+import com.android.server.wm.WindowTestsBase.ActivityBuilder;
/**
* A collection of static functions that provide access to WindowManager related test functionality.
@@ -34,7 +34,7 @@ class WindowTestUtils {
/** Creates a {@link Task} and adds it to the specified {@link Task}. */
static Task createTaskInStack(WindowManagerService service, Task stack, int userId) {
- final Task task = new ActivityTestsBase.TaskBuilder(stack.mStackSupervisor)
+ final Task task = new WindowTestsBase.TaskBuilder(stack.mStackSupervisor)
.setUserId(userId)
.setStack(stack)
.build();
@@ -49,7 +49,7 @@ class WindowTestUtils {
}
static ActivityRecord createTestActivityRecord(Task stack) {
- final ActivityRecord activity = new ActivityTestsBase.ActivityBuilder(stack.mAtmService)
+ final ActivityRecord activity = new ActivityBuilder(stack.mAtmService)
.setStack(stack)
.setCreateTask(true)
.build();
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 dc388833f338..ec19a58b17c4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -18,7 +18,13 @@ package com.android.server.wm;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.os.Process.SYSTEM_UID;
import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -37,22 +43,44 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import android.annotation.IntDef;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.IApplicationThread;
+import android.app.WindowConfiguration;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
+import android.os.Build;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.service.voice.IVoiceInteractionSession;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.IDisplayWindowInsetsController;
import android.view.IWindow;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.view.WindowManager;
+import android.window.ITaskOrganizer;
+import android.window.WindowContainerToken;
import com.android.internal.util.ArrayUtils;
import com.android.server.AttributeCache;
@@ -68,11 +96,20 @@ import java.lang.annotation.Target;
/** Common base class for window manager unit test classes. */
class WindowTestsBase extends SystemServiceTestsBase {
+ final Context mContext = getInstrumentation().getTargetContext();
+
+ // Default package name
+ static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
+
+ // Default base activity name
+ private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
+ ActivityTaskManagerService mAtm;
+ RootWindowContainer mRootWindowContainer;
+ ActivityStackSupervisor mSupervisor;
WindowManagerService mWm;
private final IWindow mIWindow = new TestIWindow();
private Session mMockSession;
- static int sNextStackId = 1000;
DisplayInfo mDisplayInfo = new DisplayInfo();
DisplayContent mDefaultDisplay;
@@ -107,6 +144,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
@Before
public void setUpBase() {
+ mAtm = mSystemServicesTestRule.getActivityTaskManagerService();
+ mSupervisor = mAtm.mStackSupervisor;
+ mRootWindowContainer = mAtm.mRootWindowContainer;
mWm = mSystemServicesTestRule.getWindowManagerService();
SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
@@ -114,7 +154,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
mTransaction = mSystemServicesTestRule.mTransaction;
mMockSession = mock(Session.class);
- getInstrumentation().getTargetContext().getSystemService(DisplayManager.class)
+ mContext.getSystemService(DisplayManager.class)
.getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(mDisplayInfo);
// Only create an additional test display for annotated test class/method because it may
@@ -328,7 +368,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
}
Task createTaskStackOnDisplay(int windowingMode, int activityType, DisplayContent dc) {
- return new ActivityTestsBase.StackBuilder(dc.mWmService.mRoot)
+ return new StackBuilder(dc.mWmService.mRoot)
.setDisplay(dc)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
@@ -339,7 +379,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
Task createTaskStackOnTaskDisplayArea(int windowingMode, int activityType,
TaskDisplayArea tda) {
- return new ActivityTestsBase.StackBuilder(tda.mWmService.mRoot)
+ return new StackBuilder(tda.mWmService.mRoot)
.setTaskDisplayArea(tda)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
@@ -371,7 +411,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
/** Creates a {@link DisplayContent} and adds it to the system. */
private DisplayContent createNewDisplay(DisplayInfo info, boolean supportIme) {
final DisplayContent display =
- new TestDisplayContent.Builder(mWm.mAtmService, info).build();
+ new TestDisplayContent.Builder(mAtm, info).build();
final DisplayContent dc = display.mDisplayContent;
// this display can show IME.
dc.mWmService.mDisplayWindowSettings.setShouldShowImeLocked(dc, supportIme);
@@ -435,11 +475,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
};
}
- /** Sets the default minimum task size to 1 so that tests can use small task sizes */
- void removeGlobalMinSizeRestriction() {
- mWm.mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
- }
-
/**
* Avoids rotating screen disturbed by some conditions. It is usually used for the default
* display that is not the instance of {@link TestDisplayContent} (it bypasses the conditions).
@@ -501,4 +536,523 @@ class WindowTestsBase extends SystemServiceTestsBase {
boolean addAllCommonWindows() default false;
@CommonTypes int[] addWindows() default {};
}
+
+ /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */
+ TestDisplayContent addNewDisplayContentAt(int position) {
+ return new TestDisplayContent.Builder(mAtm, 1000, 1500).setPosition(position).build();
+ }
+
+ /** Sets the default minimum task size to 1 so that tests can use small task sizes */
+ public void removeGlobalMinSizeRestriction() {
+ mAtm.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
+ }
+
+ /**
+ * Builder for creating new activities.
+ */
+ protected static class ActivityBuilder {
+ // An id appended to the end of the component name to make it unique
+ private static int sCurrentActivityId = 0;
+
+ private final ActivityTaskManagerService mService;
+
+ private ComponentName mComponent;
+ private String mTargetActivity;
+ private Task mTask;
+ private String mProcessName = "name";
+ private String mAffinity;
+ private int mUid = 12345;
+ private boolean mCreateTask;
+ private Task mStack;
+ private int mActivityFlags;
+ private int mLaunchMode;
+ private int mResizeMode = RESIZE_MODE_RESIZEABLE;
+ private float mMaxAspectRatio;
+ private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+ private boolean mLaunchTaskBehind;
+ private int mConfigChanges;
+ private int mLaunchedFromPid;
+ private int mLaunchedFromUid;
+ private WindowProcessController mWpc;
+ private Bundle mIntentExtras;
+
+ ActivityBuilder(ActivityTaskManagerService service) {
+ mService = service;
+ }
+
+ ActivityBuilder setComponent(ComponentName component) {
+ mComponent = component;
+ return this;
+ }
+
+ ActivityBuilder setTargetActivity(String targetActivity) {
+ mTargetActivity = targetActivity;
+ return this;
+ }
+
+ ActivityBuilder setIntentExtras(Bundle extras) {
+ mIntentExtras = extras;
+ return this;
+ }
+
+ static ComponentName getDefaultComponent() {
+ return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+ DEFAULT_COMPONENT_PACKAGE_NAME);
+ }
+
+ ActivityBuilder setTask(Task task) {
+ mTask = task;
+ return this;
+ }
+
+ ActivityBuilder setActivityFlags(int flags) {
+ mActivityFlags = flags;
+ return this;
+ }
+
+ ActivityBuilder setLaunchMode(int launchMode) {
+ mLaunchMode = launchMode;
+ return this;
+ }
+
+ ActivityBuilder setStack(Task stack) {
+ mStack = stack;
+ return this;
+ }
+
+ ActivityBuilder setCreateTask(boolean createTask) {
+ mCreateTask = createTask;
+ return this;
+ }
+
+ ActivityBuilder setProcessName(String name) {
+ mProcessName = name;
+ return this;
+ }
+
+ ActivityBuilder setUid(int uid) {
+ mUid = uid;
+ return this;
+ }
+
+ ActivityBuilder setResizeMode(int resizeMode) {
+ mResizeMode = resizeMode;
+ return this;
+ }
+
+ ActivityBuilder setMaxAspectRatio(float maxAspectRatio) {
+ mMaxAspectRatio = maxAspectRatio;
+ return this;
+ }
+
+ ActivityBuilder setScreenOrientation(int screenOrientation) {
+ mScreenOrientation = screenOrientation;
+ return this;
+ }
+
+ ActivityBuilder setLaunchTaskBehind(boolean launchTaskBehind) {
+ mLaunchTaskBehind = launchTaskBehind;
+ return this;
+ }
+
+ ActivityBuilder setConfigChanges(int configChanges) {
+ mConfigChanges = configChanges;
+ return this;
+ }
+
+ ActivityBuilder setLaunchedFromPid(int pid) {
+ mLaunchedFromPid = pid;
+ return this;
+ }
+
+ ActivityBuilder setLaunchedFromUid(int uid) {
+ mLaunchedFromUid = uid;
+ return this;
+ }
+
+ ActivityBuilder setUseProcess(WindowProcessController wpc) {
+ mWpc = wpc;
+ return this;
+ }
+
+ ActivityBuilder setAffinity(String affinity) {
+ mAffinity = affinity;
+ return this;
+ }
+
+ ActivityRecord build() {
+ SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
+ try {
+ mService.deferWindowLayout();
+ return buildInner();
+ } finally {
+ mService.continueWindowLayout();
+ }
+ }
+
+ ActivityRecord buildInner() {
+ if (mComponent == null) {
+ final int id = sCurrentActivityId++;
+ mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+ DEFAULT_COMPONENT_CLASS_NAME + id);
+ }
+
+ if (mCreateTask) {
+ mTask = new TaskBuilder(mService.mStackSupervisor)
+ .setComponent(mComponent)
+ .setStack(mStack).build();
+ } else if (mTask == null && mStack != null && DisplayContent.alwaysCreateStack(
+ mStack.getWindowingMode(), mStack.getActivityType())) {
+ // The stack can be the task root.
+ mTask = mStack;
+ }
+
+ Intent intent = new Intent();
+ intent.setComponent(mComponent);
+ if (mIntentExtras != null) {
+ intent.putExtras(mIntentExtras);
+ }
+ final ActivityInfo aInfo = new ActivityInfo();
+ aInfo.applicationInfo = new ApplicationInfo();
+ aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ aInfo.applicationInfo.packageName = mComponent.getPackageName();
+ aInfo.applicationInfo.uid = mUid;
+ aInfo.processName = mProcessName;
+ aInfo.packageName = mComponent.getPackageName();
+ aInfo.name = mComponent.getClassName();
+ if (mTargetActivity != null) {
+ aInfo.targetActivity = mTargetActivity;
+ }
+ aInfo.flags |= mActivityFlags;
+ aInfo.launchMode = mLaunchMode;
+ aInfo.resizeMode = mResizeMode;
+ aInfo.maxAspectRatio = mMaxAspectRatio;
+ aInfo.screenOrientation = mScreenOrientation;
+ aInfo.configChanges |= mConfigChanges;
+ aInfo.taskAffinity = mAffinity;
+
+ ActivityOptions options = null;
+ if (mLaunchTaskBehind) {
+ options = ActivityOptions.makeTaskLaunchBehind();
+ }
+
+ final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
+ mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
+ null, null, intent, null, aInfo /*aInfo*/, new Configuration(),
+ null /* resultTo */, null /* resultWho */, 0 /* reqCode */,
+ false /*componentSpecified*/, false /* rootVoiceInteraction */,
+ mService.mStackSupervisor, options, null /* sourceRecord */);
+ spyOn(activity);
+ if (mTask != null) {
+ // fullscreen value is normally read from resources in ctor, so for testing we need
+ // to set it somewhere else since we can't mock resources.
+ doReturn(true).when(activity).occludesParent();
+ doReturn(true).when(activity).fillsParent();
+ mTask.addChild(activity);
+ // Make visible by default...
+ activity.setVisible(true);
+ }
+
+ final WindowProcessController wpc;
+ if (mWpc != null) {
+ wpc = mWpc;
+ } else {
+ wpc = new WindowProcessController(mService,
+ aInfo.applicationInfo, mProcessName, mUid,
+ UserHandle.getUserId(12345), mock(Object.class),
+ mock(WindowProcessListener.class));
+ wpc.setThread(mock(IApplicationThread.class));
+ }
+ wpc.setThread(mock(IApplicationThread.class));
+ activity.setProcess(wpc);
+ doReturn(wpc).when(mService).getProcessController(
+ activity.processName, activity.info.applicationInfo.uid);
+
+ // Resume top activities to make sure all other signals in the system are connected.
+ mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
+ return activity;
+ }
+ }
+
+ /**
+ * Builder for creating new tasks.
+ */
+ protected static class TaskBuilder {
+ private final ActivityStackSupervisor mSupervisor;
+
+ private ComponentName mComponent;
+ private String mPackage;
+ private int mFlags = 0;
+ // Task id 0 is reserved in ARC for the home app.
+ private int mTaskId = SystemServicesTestRule.sNextTaskId++;
+ private int mUserId = 0;
+ private IVoiceInteractionSession mVoiceSession;
+ private boolean mCreateStack = true;
+
+ private Task mStack;
+ private TaskDisplayArea mTaskDisplayArea;
+
+ TaskBuilder(ActivityStackSupervisor supervisor) {
+ mSupervisor = supervisor;
+ }
+
+ TaskBuilder setComponent(ComponentName component) {
+ mComponent = component;
+ return this;
+ }
+
+ TaskBuilder setPackage(String packageName) {
+ mPackage = packageName;
+ return this;
+ }
+
+ /**
+ * Set to {@code true} by default, set to {@code false} to prevent the task from
+ * automatically creating a parent stack.
+ */
+ TaskBuilder setCreateStack(boolean createStack) {
+ mCreateStack = createStack;
+ return this;
+ }
+
+ TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
+ mVoiceSession = session;
+ return this;
+ }
+
+ TaskBuilder setFlags(int flags) {
+ mFlags = flags;
+ return this;
+ }
+
+ TaskBuilder setTaskId(int taskId) {
+ mTaskId = taskId;
+ return this;
+ }
+
+ TaskBuilder setUserId(int userId) {
+ mUserId = userId;
+ return this;
+ }
+
+ TaskBuilder setStack(Task stack) {
+ mStack = stack;
+ return this;
+ }
+
+ TaskBuilder setDisplay(DisplayContent display) {
+ mTaskDisplayArea = display.getDefaultTaskDisplayArea();
+ return this;
+ }
+
+ Task build() {
+ SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
+
+ if (mStack == null && mCreateStack) {
+ TaskDisplayArea displayArea = mTaskDisplayArea != null ? mTaskDisplayArea
+ : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
+ mStack = displayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ spyOn(mStack);
+ }
+
+ final ActivityInfo aInfo = new ActivityInfo();
+ aInfo.applicationInfo = new ApplicationInfo();
+ aInfo.applicationInfo.packageName = mPackage;
+
+ Intent intent = new Intent();
+ if (mComponent == null) {
+ mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+ DEFAULT_COMPONENT_CLASS_NAME);
+ }
+
+ intent.setComponent(mComponent);
+ intent.setFlags(mFlags);
+
+ final Task task = new Task(mSupervisor.mService, mTaskId, aInfo,
+ intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
+ null /*taskDescription*/, mStack);
+ spyOn(task);
+ task.mUserId = mUserId;
+
+ if (mStack != null) {
+ mStack.moveToFront("test");
+ mStack.addChild(task, true, true);
+ }
+
+ return task;
+ }
+ }
+
+ static class StackBuilder {
+ private final RootWindowContainer mRootWindowContainer;
+ private DisplayContent mDisplay;
+ private TaskDisplayArea mTaskDisplayArea;
+ private int mStackId = -1;
+ private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
+ private int mActivityType = ACTIVITY_TYPE_STANDARD;
+ private boolean mOnTop = true;
+ private boolean mCreateActivity = true;
+ private ActivityInfo mInfo;
+ private Intent mIntent;
+
+ StackBuilder(RootWindowContainer root) {
+ mRootWindowContainer = root;
+ mDisplay = mRootWindowContainer.getDefaultDisplay();
+ mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
+ }
+
+ StackBuilder setWindowingMode(int windowingMode) {
+ mWindowingMode = windowingMode;
+ return this;
+ }
+
+ StackBuilder setActivityType(int activityType) {
+ mActivityType = activityType;
+ return this;
+ }
+
+ StackBuilder setStackId(int stackId) {
+ mStackId = stackId;
+ return this;
+ }
+
+ /**
+ * Set the parent {@link DisplayContent} and use the default task display area. Overrides
+ * the task display area, if was set before.
+ */
+ StackBuilder setDisplay(DisplayContent display) {
+ mDisplay = display;
+ mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
+ return this;
+ }
+
+ /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
+ StackBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
+ mTaskDisplayArea = taskDisplayArea;
+ mDisplay = mTaskDisplayArea.mDisplayContent;
+ return this;
+ }
+
+ StackBuilder setOnTop(boolean onTop) {
+ mOnTop = onTop;
+ return this;
+ }
+
+ StackBuilder setCreateActivity(boolean createActivity) {
+ mCreateActivity = createActivity;
+ return this;
+ }
+
+ StackBuilder setActivityInfo(ActivityInfo info) {
+ mInfo = info;
+ return this;
+ }
+
+ StackBuilder setIntent(Intent intent) {
+ mIntent = intent;
+ return this;
+ }
+
+ Task build() {
+ SystemServicesTestRule.checkHoldsLock(mRootWindowContainer.mWmService.mGlobalLock);
+
+ final int stackId = mStackId >= 0 ? mStackId : mTaskDisplayArea.getNextStackId();
+ final Task stack = mTaskDisplayArea.createStackUnchecked(
+ mWindowingMode, mActivityType, stackId, mOnTop, mInfo, mIntent,
+ false /* createdByOrganizer */);
+ final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor;
+
+ if (mCreateActivity) {
+ new ActivityBuilder(supervisor.mService)
+ .setCreateTask(true)
+ .setStack(stack)
+ .build();
+ if (mOnTop) {
+ // We move the task to front again in order to regain focus after activity
+ // added to the stack. Or {@link DisplayContent#mPreferredTopFocusableStack}
+ // could be other stacks (e.g. home stack).
+ stack.moveToFront("createActivityStack");
+ } else {
+ stack.moveToBack("createActivityStack", null);
+ }
+ }
+ spyOn(stack);
+
+ doNothing().when(stack).startActivityLocked(
+ any(), any(), anyBoolean(), anyBoolean(), any());
+
+ return stack;
+ }
+
+ }
+
+ static class TestSplitOrganizer extends ITaskOrganizer.Stub {
+ final ActivityTaskManagerService mService;
+ Task mPrimary;
+ Task mSecondary;
+ boolean mInSplit = false;
+ // moves everything to secondary. Most tests expect this since sysui usually does it.
+ boolean mMoveToSecondaryOnEnter = true;
+ int mDisplayId;
+ TestSplitOrganizer(ActivityTaskManagerService service, int displayId) {
+ mService = service;
+ mDisplayId = displayId;
+ mService.mTaskOrganizerController.registerTaskOrganizer(this,
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ mService.mTaskOrganizerController.registerTaskOrganizer(this,
+ WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+ WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask(
+ displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
+ mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask();
+ WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask(
+ displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
+ mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask();
+ }
+ TestSplitOrganizer(ActivityTaskManagerService service) {
+ this(service,
+ service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay().mDisplayId);
+ }
+ public void setMoveToSecondaryOnEnter(boolean move) {
+ mMoveToSecondaryOnEnter = move;
+ }
+ @Override
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
+ }
+ @Override
+ public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
+ }
+ @Override
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
+ if (mInSplit) {
+ return;
+ }
+ if (info.topActivityType == ACTIVITY_TYPE_UNDEFINED) {
+ // Not populated
+ return;
+ }
+ if (info.configuration.windowConfiguration.getWindowingMode()
+ != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+ return;
+ }
+ mInSplit = true;
+ if (!mMoveToSecondaryOnEnter) {
+ return;
+ }
+ mService.mTaskOrganizerController.setLaunchRoot(mDisplayId,
+ mSecondary.mRemoteToken.toWindowContainerToken());
+ DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
+ dc.forAllTaskDisplayAreas(taskDisplayArea -> {
+ for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getStackAt(sNdx);
+ if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) {
+ stack.reparent(mSecondary, POSITION_BOTTOM);
+ }
+ }
+ });
+ }
+ @Override
+ public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
+ }
+ }
}
diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
index 6861ad1b2e2d..4986d1883307 100644
--- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java
+++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
@@ -307,7 +307,7 @@ public class AppTimeLimitController {
}
} else {
if (mActives > mObserved.length) {
- // Try to get to a sane state and log the issue
+ // Try to get to a valid state and log the issue
mActives = mObserved.length;
final UserData user = mUserRef.get();
if (user == null) return;
@@ -334,7 +334,7 @@ public class AppTimeLimitController {
cancelCheckTimeoutLocked(this);
} else {
if (mActives < 0) {
- // Try to get to a sane state and log the issue
+ // Try to get to a valid state and log the issue
mActives = 0;
final UserData user = mUserRef.get();
if (user == null) return;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 9b18ec644ceb..2fd6c4249f99 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -92,6 +92,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.io.BufferedReader;
@@ -291,27 +292,26 @@ public class UsageStatsService extends SystemService implements
}
@Override
- public void onStartUser(UserInfo userInfo) {
+ public void onUserStarting(@NonNull TargetUser user) {
// Create an entry in the user state map to indicate that the user has been started but
// not necessarily unlocked. This will ensure that reported events are flushed to disk
// event if the user is never unlocked (following the logic in #flushToDiskLocked)
- mUserState.put(userInfo.id, null);
- super.onStartUser(userInfo);
+ mUserState.put(user.getUserIdentifier(), null);
}
@Override
- public void onUnlockUser(@NonNull UserInfo userInfo) {
- mHandler.obtainMessage(MSG_UNLOCKED_USER, userInfo.id, 0).sendToTarget();
- super.onUnlockUser(userInfo);
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ mHandler.obtainMessage(MSG_UNLOCKED_USER, user.getUserIdentifier(), 0).sendToTarget();
}
@Override
- public void onStopUser(@NonNull UserInfo userInfo) {
+ public void onUserStopping(@NonNull TargetUser user) {
+ final UserInfo userInfo = user.getUserInfo();
+
synchronized (mLock) {
// User was started but never unlocked so no need to report a user stopped event
if (!mUserUnlockedStates.get(userInfo.id)) {
persistPendingEventsLocked(userInfo.id);
- super.onStopUser(userInfo);
return;
}
@@ -326,7 +326,6 @@ public class UsageStatsService extends SystemService implements
mUserUnlockedStates.put(userInfo.id, false);
mUserState.put(userInfo.id, null); // release the service (mainly for GC)
}
- super.onStopUser(userInfo);
}
private void onUserUnlocked(int userId) {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 534fe036ba87..0ea84da54b60 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -221,14 +221,6 @@ public class SoundTriggerService extends SystemService {
}
}
- @Override
- public void onStartUser(int userHandle) {
- }
-
- @Override
- public void onSwitchUser(int userHandle) {
- }
-
private synchronized void initSoundTriggerHelper() {
if (mSoundTriggerHelper == null) {
mSoundTriggerHelper = new SoundTriggerHelper(mContext);
@@ -1289,27 +1281,25 @@ public class SoundTriggerService extends SystemService {
attributesBuilder.setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD);
AudioAttributes attributes = attributesBuilder.build();
- // Use same AudioFormat processing as in RecognitionEvent.fromParcel
AudioFormat originalFormat = event.getCaptureFormat();
- AudioFormat captureFormat = (new AudioFormat.Builder())
- .setChannelMask(originalFormat.getChannelMask())
- .setEncoding(originalFormat.getEncoding())
- .setSampleRate(originalFormat.getSampleRate())
- .build();
-
- int bufferSize = AudioRecord.getMinBufferSize(
- captureFormat.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED
- ? AudioFormat.SAMPLE_RATE_HZ_MAX
- : captureFormat.getSampleRate(),
- captureFormat.getChannelCount() == 2
- ? AudioFormat.CHANNEL_IN_STEREO
- : AudioFormat.CHANNEL_IN_MONO,
- captureFormat.getEncoding());
sEventLogger.log(new SoundTriggerLogger.StringEvent("createAudioRecordForEvent"));
- return new AudioRecord(attributes, captureFormat, bufferSize,
- event.getCaptureSession());
+ try {
+ return (new AudioRecord.Builder())
+ .setAudioAttributes(attributes)
+ .setAudioFormat((new AudioFormat.Builder())
+ .setChannelMask(originalFormat.getChannelMask())
+ .setEncoding(originalFormat.getEncoding())
+ .setSampleRate(originalFormat.getSampleRate())
+ .build())
+ .setSessionId(event.getCaptureSession())
+ .build();
+ } catch (IllegalArgumentException | UnsupportedOperationException e) {
+ Slog.w(TAG, mPuuid + ": createAudioRecordForEvent(" + event
+ + "), failed to create AudioRecord");
+ return null;
+ }
}
@Override
@@ -1339,8 +1329,10 @@ public class SoundTriggerService extends SystemService {
// Currently we need to start and release the audio record to reset
// the DSP even if we don't want to process the event
- capturedData.startRecording();
- capturedData.release();
+ if (capturedData != null) {
+ capturedData.startRecording();
+ capturedData.release();
+ }
}
}));
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 9621f68f9d6c..0f898f8e679e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -189,10 +189,10 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
- public void onSwitchUser(@NonNull UserInfo from, @NonNull UserInfo to) {
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
if (DEBUG_USER) Slog.d(TAG, "onSwitchUser(" + from + " > " + to + ")");
- mServiceStub.switchUser(to.id);
+ mServiceStub.switchUser(to.getUserIdentifier());
}
class LocalService extends VoiceInteractionManagerInternal {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index a1577b1e83b1..0469fa56e648 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -470,7 +470,7 @@ public final class Call {
/**
* When set for a call, indicates that this {@code Call} can be transferred to another
* number.
- * Call supports the blind and assured call transfer feature.
+ * Call supports the confirmed and unconfirmed call transfer feature.
*
* @hide
*/
@@ -1596,8 +1596,8 @@ public final class Call {
* Instructs this {@code Call} to be transferred to another number.
*
* @param targetNumber The address to which the call will be transferred.
- * @param isConfirmationRequired if {@code true} it will initiate ASSURED transfer,
- * if {@code false}, it will initiate BLIND transfer.
+ * @param isConfirmationRequired if {@code true} it will initiate a confirmed transfer,
+ * if {@code false}, it will initiate an unconfirmed transfer.
*
* @hide
*/
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index fe813763e3c7..00b711643fe6 100755
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -393,7 +393,7 @@ public abstract class Connection extends Conferenceable {
/**
* Indicates that this {@code Connection} can be transferred to another
* number.
- * Connection supports the blind and assured call transfer feature.
+ * Connection supports the confirmed and unconfirmed call transfer feature.
* @hide
*/
public static final int CAPABILITY_TRANSFER = 0x08000000;
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 780a7c257aa7..3646647e9734 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1880,6 +1880,7 @@ public abstract class ConnectionService extends Service {
mConferenceById.put(callId, conference);
mIdByConference.put(conference, callId);
+
conference.addListener(mConferenceListener);
ParcelableConference parcelableConference = new ParcelableConference.Builder(
request.getAccountHandle(), conference.getState())
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index dd6c15311651..ab35affe9099 100755
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -107,8 +107,8 @@ public final class InCallAdapter {
*
* @param callId The identifier of the call to transfer.
* @param targetNumber The address to transfer to.
- * @param isConfirmationRequired if {@code true} it will initiate ASSURED transfer,
- * if {@code false}, it will initiate BLIND transfer.
+ * @param isConfirmationRequired if {@code true} it will initiate a confirmed transfer,
+ * if {@code false}, it will initiate unconfirmed transfer.
*/
public void transferCall(@NonNull String callId, @NonNull Uri targetNumber,
boolean isConfirmationRequired) {
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index ef94c7677a17..09c16595e2c7 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -316,6 +316,7 @@ package android.telephony {
method @Deprecated public int getDataConnectionApnTypeBitMask();
method @Deprecated public int getDataConnectionFailCause();
method @Deprecated public int getDataConnectionState();
+ method public int getId();
}
public final class PreciseDisconnectCause {
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index 48794cb37853..502bfa3749eb 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -47,7 +47,7 @@ public final class LocationAccessPolicy {
ALLOWED,
/**
* Indicates that the denial is due to a transient device state
- * (e.g. app-ops, location master switch)
+ * (e.g. app-ops, location main switch)
*/
DENIED_SOFT,
/**
@@ -316,7 +316,7 @@ public final class LocationAccessPolicy {
return LocationPermissionResult.ALLOWED;
}
- // Check the system-wide requirements. If the location master switch is off or
+ // Check the system-wide requirements. If the location main switch is off or
// the app's profile isn't in foreground, return a soft denial.
if (!checkSystemLocationAccess(context, query.callingUid, query.callingPid)) {
return LocationPermissionResult.DENIED_SOFT;
@@ -340,7 +340,7 @@ public final class LocationAccessPolicy {
}
// At this point, we're out of location checks to do. If the app bypassed all the previous
- // ones due to the SDK grandfathering schemes, allow it access.
+ // ones due to the SDK backwards compatibility schemes, allow it access.
return LocationPermissionResult.ALLOWED;
}
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 71a1964210b0..0c463949b14a 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -74,7 +74,8 @@ public final class TelephonyPermissions {
* <li>return false: if the caller lacks all of these permissions and doesn't support runtime
* permissions. This implies that the user revoked the ability to read phone state
* manually (via AppOps). In this case we can't throw as it would break app compatibility,
- * so we return false to indicate that the calling function should return dummy data.
+ * so we return false to indicate that the calling function should return placeholder
+ * data.
* </ul>
*
* <p>Note: for simplicity, this method always returns false for callers using legacy
@@ -119,7 +120,8 @@ public final class TelephonyPermissions {
* <li>return false: if the caller lacks all of these permissions and doesn't support runtime
* permissions. This implies that the user revoked the ability to read phone state
* manually (via AppOps). In this case we can't throw as it would break app compatibility,
- * so we return false to indicate that the calling function should return dummy data.
+ * so we return false to indicate that the calling function should return placeholder
+ * data.
* </ul>
*
* <p>Note: for simplicity, this method always returns false for callers using legacy
@@ -225,7 +227,7 @@ public final class TelephonyPermissions {
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission. In this case the caller would expect to have access to the device
* identifiers so false is returned instead of throwing a SecurityException to indicate
- * the calling function should return dummy data.
+ * the calling function should return placeholder data.
* </ul>
*/
public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context,
@@ -249,7 +251,7 @@ public final class TelephonyPermissions {
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission or carrier privileges. In this case the caller would expect to have access
* to the device identifiers so false is returned instead of throwing a SecurityException
- * to indicate the calling function should return dummy data.
+ * to indicate the calling function should return placeholder data.
* </ul>
*/
public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
@@ -271,7 +273,7 @@ public final class TelephonyPermissions {
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission. In this case the caller would expect to have access to the device
* identifiers so false is returned instead of throwing a SecurityException to indicate
- * the calling function should return dummy data.
+ * the calling function should return placeholder data.
* </ul>
*/
public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
@@ -295,7 +297,7 @@ public final class TelephonyPermissions {
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission. In this case the caller would expect to have access to the device
* identifiers so false is returned instead of throwing a SecurityException to indicate
- * the calling function should return dummy data.
+ * the calling function should return placeholder data.
* </ul>
*/
private static boolean checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
diff --git a/telephony/common/com/google/android/mms/pdu/PduComposer.java b/telephony/common/com/google/android/mms/pdu/PduComposer.java
index 5e1f556f4c4a..7af0d1b09eed 100644
--- a/telephony/common/com/google/android/mms/pdu/PduComposer.java
+++ b/telephony/common/com/google/android/mms/pdu/PduComposer.java
@@ -1051,7 +1051,7 @@ public class PduComposer {
}
if (dataLength != (attachment.getLength() - headerLength)) {
- throw new RuntimeException("BUG: Length sanity check failed");
+ throw new RuntimeException("BUG: Length correctness check failed");
}
mStack.pop();
diff --git a/telephony/common/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java
index fcd5b8ff57a8..b61ad3680c6c 100755
--- a/telephony/common/com/google/android/mms/pdu/PduPersister.java
+++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java
@@ -72,7 +72,7 @@ public class PduPersister {
private static final boolean DEBUG = false;
private static final boolean LOCAL_LOGV = false;
- private static final long DUMMY_THREAD_ID = Long.MAX_VALUE;
+ private static final long PLACEHOLDER_THREAD_ID = Long.MAX_VALUE;
/**
* The uri of temporary drm objects.
@@ -1340,7 +1340,7 @@ public class PduPersister {
// Save parts first to avoid inconsistent message is loaded
// while saving the parts.
- long dummyId = System.currentTimeMillis(); // Dummy ID of the msg.
+ long placeholderId = System.currentTimeMillis(); // Placeholder ID of the msg.
// Figure out if this PDU is a text-only message
boolean textOnly = true;
@@ -1364,7 +1364,7 @@ public class PduPersister {
for (int i = 0; i < partsNum; i++) {
PduPart part = body.getPart(i);
messageSize += part.getDataLength();
- persistPart(part, dummyId, preOpenedFiles);
+ persistPart(part, placeholderId, preOpenedFiles);
// If we've got anything besides text/plain or SMIL part, then we've got
// an mms message with some other type of attachment.
@@ -1395,14 +1395,14 @@ public class PduPersister {
throw new MmsException("persist() failed: return null.");
}
// Get the real ID of the PDU and update all parts which were
- // saved with the dummy ID.
+ // saved with the placeholder ID.
msgId = ContentUris.parseId(res);
}
values = new ContentValues(1);
values.put(Part.MSG_ID, msgId);
SqliteWrapper.update(mContext, mContentResolver,
- Uri.parse("content://mms/" + dummyId + "/part"),
+ Uri.parse("content://mms/" + placeholderId + "/part"),
values, null, null);
// We should return the longest URI of the persisted PDU, for
// example, if input URI is "content://mms/inbox" and the _ID of
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 8e50bba38e84..766019ec382a 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -149,7 +149,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
- mSsRsrq = inRangeOrUnavailable(ssRsrq, -20, -3);
+ mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
updateLevel(null, null);
}
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index 3f671ca2d809..18d6f467ba7b 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -509,7 +509,7 @@ public class MbmsDownloadSession implements AutoCloseable {
* provided directory is the same as what has been previously configured.
*
* The {@link File} supplied as a root temp file directory must already exist. If not, an
- * {@link IllegalArgumentException} will be thrown. In addition, as an additional sanity
+ * {@link IllegalArgumentException} will be thrown. In addition, as an additional correctness
* check, an {@link IllegalArgumentException} will be thrown if you attempt to set the temp
* file root directory to one of your data roots (the value of {@link Context#getDataDir()},
* {@link Context#getFilesDir()}, or {@link Context#getCacheDir()}).
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 3dbbf4138b02..fd9f46011c7e 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -28,11 +28,15 @@ import android.net.LinkProperties;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType;
import android.telephony.data.ApnSetting;
+import android.telephony.data.DataCallResponse;
+
+import com.android.internal.telephony.util.TelephonyUtils;
import java.util.Objects;
@@ -53,11 +57,11 @@ import java.util.Objects;
*
*/
public final class PreciseDataConnectionState implements Parcelable {
+ private final @TransportType int mTransportType;
+ private final int mId;
private final @DataState int mState;
private final @NetworkType int mNetworkType;
private final @DataFailureCause int mFailCause;
- private final @ApnType int mApnTypes;
- private final String mApn;
private final LinkProperties mLinkProperties;
private final ApnSetting mApnSetting;
@@ -76,35 +80,36 @@ public final class PreciseDataConnectionState implements Parcelable {
@ApnType int apnTypes, @NonNull String apn,
@Nullable LinkProperties linkProperties,
@DataFailureCause int failCause) {
- this(state, networkType, apnTypes, apn, linkProperties, failCause, null);
+ this(AccessNetworkConstants.TRANSPORT_TYPE_INVALID, -1, state, networkType,
+ linkProperties, failCause, new ApnSetting.Builder()
+ .setApnTypeBitmask(apnTypes)
+ .setApnName(apn)
+ .setEntryName(apn)
+ .build());
}
/**
* Constructor of PreciseDataConnectionState
*
+ * @param transportType The transport of the data connection
+ * @param id The id of the data connection
* @param state The state of the data connection
* @param networkType The access network that is/would carry this data connection
- * @param apnTypes The APN types that this data connection carries
- * @param apn The APN of this data connection
* @param linkProperties If the data connection is connected, the properties of the connection
* @param failCause In case a procedure related to this data connection fails, a non-zero error
* code indicating the cause of the failure.
* @param apnSetting If there is a valid APN for this Data Connection, then the APN Settings;
* if there is no valid APN setting for the specific type, then this will be null
- * @hide
*/
- private PreciseDataConnectionState(@DataState int state,
- @NetworkType int networkType,
- @ApnType int apnTypes,
- @NonNull String apn,
- @Nullable LinkProperties linkProperties,
- @DataFailureCause int failCause,
- @Nullable ApnSetting apnSetting) {
+ private PreciseDataConnectionState(@TransportType int transportType, int id,
+ @DataState int state, @NetworkType int networkType,
+ @Nullable LinkProperties linkProperties, @DataFailureCause int failCause,
+ @Nullable ApnSetting apnSetting) {
+ mTransportType = transportType;
+ mId = id;
mState = state;
mNetworkType = networkType;
- mApnTypes = apnTypes;
- mApn = apn;
mLinkProperties = linkProperties;
mFailCause = failCause;
mApnSetting = apnSetting;
@@ -116,13 +121,13 @@ public final class PreciseDataConnectionState implements Parcelable {
* @hide
*/
private PreciseDataConnectionState(Parcel in) {
+ mTransportType = in.readInt();
+ mId = in.readInt();
mState = in.readInt();
mNetworkType = in.readInt();
- mApnTypes = in.readInt();
- mApn = in.readString();
- mLinkProperties = (LinkProperties) in.readParcelable(null);
+ mLinkProperties = in.readParcelable(LinkProperties.class.getClassLoader());
mFailCause = in.readInt();
- mApnSetting = (ApnSetting) in.readParcelable(null);
+ mApnSetting = in.readParcelable(ApnSetting.class.getClassLoader());
}
/**
@@ -152,7 +157,29 @@ public final class PreciseDataConnectionState implements Parcelable {
}
/**
- * Returns the high-level state of this data connection.
+ * @return The transport type of this data connection.
+ */
+ public @TransportType int getTransportType() {
+ return mTransportType;
+ }
+
+ /**
+ * @return The unique id of the data connection
+ *
+ * Note this is the id assigned in {@link DataCallResponse}.
+ * The id remains the same for data connection handover between
+ * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} and
+ * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN}
+ *
+ * @hide
+ */
+ @SystemApi
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * @return The high-level state of this data connection.
*/
public @DataState int getState() {
return mState;
@@ -181,7 +208,7 @@ public final class PreciseDataConnectionState implements Parcelable {
@Deprecated
@SystemApi
public @ApnType int getDataConnectionApnTypeBitMask() {
- return mApnTypes;
+ return (mApnSetting != null) ? mApnSetting.getApnTypeBitmask() : ApnSetting.TYPE_NONE;
}
/**
@@ -194,7 +221,7 @@ public final class PreciseDataConnectionState implements Parcelable {
@SystemApi
@Deprecated
public String getDataConnectionApn() {
- return mApn;
+ return (mApnSetting != null) ? mApnSetting.getApnName() : "";
}
/**
@@ -230,7 +257,9 @@ public final class PreciseDataConnectionState implements Parcelable {
/**
* Return the APN Settings for this data connection.
*
- * @return the ApnSetting that was used to configure this data connection.
+ * @return the ApnSetting that was used to configure this data connection. Note that a data
+ * connection cannot be established without a valid {@link ApnSetting}. The return value would
+ * never be {@code null} even though it has {@link Nullable} annotation.
*/
public @Nullable ApnSetting getApnSetting() {
return mApnSetting;
@@ -243,10 +272,10 @@ public final class PreciseDataConnectionState implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mTransportType);
+ out.writeInt(mId);
out.writeInt(mState);
out.writeInt(mNetworkType);
- out.writeInt(mApnTypes);
- out.writeString(mApn);
out.writeParcelable(mLinkProperties, flags);
out.writeInt(mFailCause);
out.writeParcelable(mApnSetting, flags);
@@ -266,8 +295,8 @@ public final class PreciseDataConnectionState implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mState, mNetworkType, mFailCause, mApnTypes, mApn, mLinkProperties,
- mApnSetting);
+ return Objects.hash(mTransportType, mId, mState, mNetworkType, mFailCause,
+ mLinkProperties, mApnSetting);
}
@@ -276,11 +305,11 @@ public final class PreciseDataConnectionState implements Parcelable {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PreciseDataConnectionState that = (PreciseDataConnectionState) o;
- return mState == that.mState
+ return mTransportType == that.mTransportType
+ && mId == that.mId
+ && mState == that.mState
&& mNetworkType == that.mNetworkType
&& mFailCause == that.mFailCause
- && mApnTypes == that.mApnTypes
- && Objects.equals(mApn, that.mApn)
&& Objects.equals(mLinkProperties, that.mLinkProperties)
&& Objects.equals(mApnSetting, that.mApnSetting);
}
@@ -290,13 +319,14 @@ public final class PreciseDataConnectionState implements Parcelable {
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("Data Connection state: " + mState);
- sb.append(", Network type: " + mNetworkType);
- sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes));
- sb.append(", APN: " + mApn);
- sb.append(", Link properties: " + mLinkProperties);
- sb.append(", Fail cause: " + DataFailCause.toString(mFailCause));
- sb.append(", Apn Setting: " + mApnSetting);
+ sb.append(" state: " + TelephonyUtils.dataStateToString(mState));
+ sb.append(", transport: "
+ + AccessNetworkConstants.transportTypeToString(mTransportType));
+ sb.append(", id: " + mId);
+ sb.append(", network type: " + TelephonyManager.getNetworkTypeName(mNetworkType));
+ sb.append(", APN Setting: " + mApnSetting);
+ sb.append(", link properties: " + mLinkProperties);
+ sb.append(", fail cause: " + DataFailCause.toString(mFailCause));
return sb.toString();
}
@@ -307,18 +337,21 @@ public final class PreciseDataConnectionState implements Parcelable {
* @hide
*/
public static final class Builder {
+ /** The transport type of the data connection */
+ private @TransportType int mTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+
+ /**
+ * The unique ID of the data connection. This is the id assigned in
+ * {@link DataCallResponse)}.
+ */
+ private int mId = -1;
+
/** The state of the data connection */
private @DataState int mState = TelephonyManager.DATA_UNKNOWN;
/** The network type associated with this data connection */
private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- /** The APN types that this data connection carries */
- private @ApnType int mApnTypes = ApnSetting.TYPE_NONE;
-
- /** The APN of this data connection */
- private @NonNull String mApn = "";
-
/** If the data connection is connected, the properties of the connection */
private @Nullable LinkProperties mLinkProperties = null;
@@ -332,46 +365,46 @@ public final class PreciseDataConnectionState implements Parcelable {
private @Nullable ApnSetting mApnSetting = null;
/**
- * Set the state of the data connection.
+ * Set the transport type of the data connection.
*
- * @param state The state of the data connection
+ * @param transportType The transport type of the data connection
* @return The builder
*/
- public Builder setState(@DataState int state) {
- mState = state;
+ public @NonNull Builder setTransportType(@TransportType int transportType) {
+ mTransportType = transportType;
return this;
}
/**
- * Set the network type associated with this data connection.
+ * Set the id of the data connection.
*
- * @param networkType The network type
+ * @param id The id of the data connection
* @return The builder
*/
- public Builder setNetworkType(@NetworkType int networkType) {
- mNetworkType = networkType;
+ public @NonNull Builder setId(int id) {
+ mId = id;
return this;
}
/**
- * Set the APN types that this data connection carries
+ * Set the state of the data connection.
*
- * @param apnTypes The APN types
+ * @param state The state of the data connection
* @return The builder
*/
- public Builder setApnTypes(@ApnType int apnTypes) {
- mApnTypes = apnTypes;
+ public @NonNull Builder setState(@DataState int state) {
+ mState = state;
return this;
}
/**
- * Set the APN of this data connection
+ * Set the network type associated with this data connection.
*
- * @param apn The APN of this data connection
+ * @param networkType The network type
* @return The builder
*/
- public Builder setApn(@NonNull String apn) {
- mApn = apn;
+ public @NonNull Builder setNetworkType(@NetworkType int networkType) {
+ mNetworkType = networkType;
return this;
}
@@ -381,7 +414,7 @@ public final class PreciseDataConnectionState implements Parcelable {
* @param linkProperties Link properties
* @return The builder
*/
- public Builder setLinkProperties(@NonNull LinkProperties linkProperties) {
+ public @NonNull Builder setLinkProperties(LinkProperties linkProperties) {
mLinkProperties = linkProperties;
return this;
}
@@ -393,7 +426,7 @@ public final class PreciseDataConnectionState implements Parcelable {
* error code indicating the cause of the failure.
* @return The builder
*/
- public Builder setFailCause(@DataFailureCause int failCause) {
+ public @NonNull Builder setFailCause(@DataFailureCause int failCause) {
mFailCause = failCause;
return this;
}
@@ -404,7 +437,7 @@ public final class PreciseDataConnectionState implements Parcelable {
* @param apnSetting APN setting
* @return This builder
*/
- public Builder setApnSetting(@NonNull ApnSetting apnSetting) {
+ public @NonNull Builder setApnSetting(@NonNull ApnSetting apnSetting) {
mApnSetting = apnSetting;
return this;
}
@@ -415,7 +448,7 @@ public final class PreciseDataConnectionState implements Parcelable {
* @return The {@link PreciseDataConnectionState} instance
*/
public PreciseDataConnectionState build() {
- return new PreciseDataConnectionState(mState, mNetworkType, mApnTypes, mApn,
+ return new PreciseDataConnectionState(mTransportType, mId, mState, mNetworkType,
mLinkProperties, mFailCause, mApnSetting);
}
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 06af04aea421..2b2608724e12 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1797,8 +1797,7 @@ public final class SmsManager {
* operation is performed on the correct subscription.
* </p>
*
- * @param messageIndex This is the same index used to access a message
- * from {@link #getMessagesFromIcc()}.
+ * @param messageIndex the message index of the message in the ICC (1-based index).
* @return true for success, false if the operation fails. Failure can be due to IPC failure,
* RIL/modem error which results in SMS failed to be deleted on SIM
*
@@ -1880,7 +1879,7 @@ public final class SmsManager {
* operation is performed on the correct subscription.
* </p>
*
- * @return <code>List</code> of <code>SmsMessage</code> objects
+ * @return <code>List</code> of <code>SmsMessage</code> objects for valid records only.
*
* {@hide}
*/
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 4ad52ae5e077..a71a965b1bdb 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -94,10 +94,9 @@ public class SubscriptionManager {
/** An invalid subscription identifier */
public static final int INVALID_SUBSCRIPTION_ID = -1;
- /** Base value for Dummy SUBSCRIPTION_ID's. */
- /** FIXME: Remove DummySubId's, but for now have them map just below INVALID_SUBSCRIPTION_ID
- /** @hide */
- public static final int DUMMY_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
+ /** Base value for placeholder SUBSCRIPTION_ID's. */
+ /** @hide */
+ public static final int PLACEHOLDER_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
/** An invalid phone identifier */
/** @hide */
diff --git a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
index e8f3f1ebb6cf..eadb726bf63b 100644
--- a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
+++ b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
@@ -92,8 +92,8 @@ public final class VisualVoicemailSmsFilterSettings implements Parcelable {
}
/**
- * Sets the originating number whitelist for the visual voicemail SMS filter. If the list is
- * not null only the SMS messages from a number in the list can be considered as a visual
+ * Sets the originating number allow list for the visual voicemail SMS filter. If the list
+ * is not null only the SMS messages from a number in the list can be considered as a visual
* voicemail SMS. Otherwise, messages from any address will be considered.
*/
public Builder setOriginatingNumbers(List<String> originatingNumbers) {
@@ -133,7 +133,7 @@ public final class VisualVoicemailSmsFilterSettings implements Parcelable {
public final String clientPrefix;
/**
- * The originating number whitelist for the visual voicemail SMS filter of a phone account. If
+ * The originating number allow list for the visual voicemail SMS filter of a phone account. If
* the list is not null only the SMS messages from a number in the list can be considered as a
* visual voicemail SMS. Otherwise, messages from any address will be considered.
*/
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index bfb54b008cd8..ff9329ef9742 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1214,12 +1214,16 @@ public class ApnSetting implements Parcelable {
return false;
}
- // TODO - if we have this function we should also have hashCode.
- // Also should handle changes in type order and perhaps case-insensitivity.
+ @Override
+ public int hashCode() {
+ return Objects.hash(mApnName, mProxyAddress, mProxyPort, mMmsc, mMmsProxyAddress,
+ mMmsProxyPort, mUser, mPassword, mAuthType, mApnTypeBitmask, mId, mOperatorNumeric,
+ mProtocol, mRoamingProtocol, mMtu, mCarrierEnabled, mNetworkTypeBitmask, mProfileId,
+ mPersistent, mMaxConns, mWaitTime, mMaxConnsTime, mMvnoType, mMvnoMatchData,
+ mApnSetId, mCarrierId, mSkip464Xlat);
+ }
- /**
- * @hide
- */
+ @Override
public boolean equals(Object o) {
if (o instanceof ApnSetting == false) {
return false;
@@ -1643,7 +1647,7 @@ public class ApnSetting implements Parcelable {
*
* <pre><code>
* // Create an MMS proxy address with a hostname. A network might not be
- * // available, so supply a dummy (0.0.0.0) IPv4 address to avoid DNS lookup.
+ * // available, so supply a placeholder (0.0.0.0) IPv4 address to avoid DNS lookup.
* String host = "mms.example.com";
* byte[] ipAddress = new byte[4];
* InetAddress mmsProxy;
@@ -1828,7 +1832,8 @@ public class ApnSetting implements Parcelable {
* {@link java.net.InetAddress#getAllByName getAllByName()} require DNS for hostname
* resolution. To avoid this requirement when setting a hostname, call
* {@link java.net.InetAddress#getByAddress(java.lang.String, byte[])} with both the
- * hostname and a dummy IP address. See {@link ApnSetting.Builder above} for an example.
+ * hostname and a placeholder IP address. See {@link ApnSetting.Builder above} for an
+ * example.
*
* @param proxy the proxy address to set for the APN
* @deprecated use {@link #setProxyAddress(String)} instead.
@@ -1882,7 +1887,8 @@ public class ApnSetting implements Parcelable {
* {@link java.net.InetAddress#getAllByName getAllByName()} require DNS for hostname
* resolution. To avoid this requirement when setting a hostname, call
* {@link java.net.InetAddress#getByAddress(java.lang.String, byte[])} with both the
- * hostname and a dummy IP address. See {@link ApnSetting.Builder above} for an example.
+ * hostname and a placeholder IP address. See {@link ApnSetting.Builder above} for an
+ * example.
*
* @param mmsProxy the MMS proxy address to set for the APN
* @deprecated use {@link #setMmsProxyAddress(String)} instead.
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index 80c38cbfc39a..8857b9b36d0c 100755
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -815,7 +815,7 @@ public class ImsCallSession {
* Transfers an ongoing call.
*
* @param number number to be transferred to.
- * @param isConfirmationRequired indicates blind or assured transfer.
+ * @param isConfirmationRequired indicates whether confirmation of the transfer is required.
*/
public void transfer(@NonNull String number, boolean isConfirmationRequired) {
if (mClosed) {
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 0d6b31d349e1..30389a290368 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -27,7 +27,8 @@ import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-
+import java.util.HashMap;
+import java.util.Map;
/**
* Provides details on why an IMS call failed. Applications can use the methods in this class to
* get local or network fault behind an IMS services failure. For example, if the code is
@@ -1095,6 +1096,196 @@ public final class ImsReasonInfo implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface ImsCode {}
+
+ private static final Map<Integer, String> sImsCodeMap;
+ static {
+ sImsCodeMap = new HashMap<>();
+ sImsCodeMap.put(CODE_UNSPECIFIED, "CODE_UNSPECIFIED");
+ sImsCodeMap.put(CODE_LOCAL_ILLEGAL_ARGUMENT, "CODE_LOCAL_ILLEGAL_ARGUMENT");
+ sImsCodeMap.put(CODE_LOCAL_ILLEGAL_STATE, "CODE_LOCAL_ILLEGAL_STATE");
+ sImsCodeMap.put(CODE_LOCAL_INTERNAL_ERROR, "CODE_LOCAL_INTERNAL_ERROR");
+ sImsCodeMap.put(CODE_LOCAL_IMS_SERVICE_DOWN, "CODE_LOCAL_IMS_SERVICE_DOWN");
+ sImsCodeMap.put(CODE_LOCAL_NO_PENDING_CALL, "CODE_LOCAL_NO_PENDING_CALL");
+ sImsCodeMap.put(CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE,
+ "CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE");
+ sImsCodeMap.put(CODE_LOCAL_POWER_OFF, "CODE_LOCAL_POWER_OFF");
+ sImsCodeMap.put(CODE_LOCAL_LOW_BATTERY, "CODE_LOCAL_LOW_BATTERY");
+ sImsCodeMap.put(CODE_LOCAL_NETWORK_NO_SERVICE, "CODE_LOCAL_NETWORK_NO_SERVICE");
+ sImsCodeMap.put(CODE_LOCAL_NETWORK_NO_LTE_COVERAGE, "CODE_LOCAL_NETWORK_NO_LTE_COVERAGE");
+ sImsCodeMap.put(CODE_LOCAL_NETWORK_ROAMING, "CODE_LOCAL_NETWORK_ROAMING");
+ sImsCodeMap.put(CODE_LOCAL_NETWORK_IP_CHANGED, "CODE_LOCAL_NETWORK_IP_CHANGED");
+ sImsCodeMap.put(CODE_LOCAL_SERVICE_UNAVAILABLE, "CODE_LOCAL_SERVICE_UNAVAILABLE");
+ sImsCodeMap.put(CODE_LOCAL_NOT_REGISTERED, "CODE_LOCAL_NOT_REGISTERED");
+ sImsCodeMap.put(CODE_LOCAL_CALL_EXCEEDED, "CODE_LOCAL_CALL_EXCEEDED");
+ sImsCodeMap.put(CODE_LOCAL_CALL_BUSY, "CODE_LOCAL_CALL_BUSY");
+ sImsCodeMap.put(CODE_LOCAL_CALL_DECLINE, "CODE_LOCAL_CALL_DECLINE");
+ sImsCodeMap.put(CODE_LOCAL_CALL_VCC_ON_PROGRESSING, "CODE_LOCAL_CALL_VCC_ON_PROGRESSING");
+ sImsCodeMap.put(CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED,
+ "CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED");
+ sImsCodeMap.put(CODE_LOCAL_CALL_CS_RETRY_REQUIRED, "CODE_LOCAL_CALL_CS_RETRY_REQUIRED");
+ sImsCodeMap.put(CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED,
+ "CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED");
+ sImsCodeMap.put(CODE_LOCAL_CALL_TERMINATED, "CODE_LOCAL_CALL_TERMINATED");
+ sImsCodeMap.put(CODE_LOCAL_HO_NOT_FEASIBLE, "CODE_LOCAL_HO_NOT_FEASIBLE");
+ sImsCodeMap.put(CODE_TIMEOUT_1XX_WAITING, "CODE_TIMEOUT_1XX_WAITING");
+ sImsCodeMap.put(CODE_TIMEOUT_NO_ANSWER, "CODE_TIMEOUT_NO_ANSWER");
+ sImsCodeMap.put(CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE, "CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE");
+ sImsCodeMap.put(CODE_CALL_BARRED, "CODE_CALL_BARRED");
+ sImsCodeMap.put(CODE_FDN_BLOCKED, "CODE_FDN_BLOCKED");
+ sImsCodeMap.put(CODE_IMEI_NOT_ACCEPTED, "CODE_IMEI_NOT_ACCEPTED");
+ sImsCodeMap.put(CODE_DIAL_MODIFIED_TO_USSD, "CODE_DIAL_MODIFIED_TO_USSD");
+ sImsCodeMap.put(CODE_DIAL_MODIFIED_TO_SS, "CODE_DIAL_MODIFIED_TO_SS");
+ sImsCodeMap.put(CODE_DIAL_MODIFIED_TO_DIAL, "CODE_DIAL_MODIFIED_TO_DIAL");
+ sImsCodeMap.put(CODE_DIAL_MODIFIED_TO_DIAL_VIDEO, "CODE_DIAL_MODIFIED_TO_DIAL_VIDEO");
+ sImsCodeMap.put(CODE_DIAL_VIDEO_MODIFIED_TO_DIAL, "CODE_DIAL_VIDEO_MODIFIED_TO_DIAL");
+ sImsCodeMap.put(CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO,
+ "CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO");
+ sImsCodeMap.put(CODE_DIAL_VIDEO_MODIFIED_TO_SS, "CODE_DIAL_VIDEO_MODIFIED_TO_SS");
+ sImsCodeMap.put(CODE_DIAL_VIDEO_MODIFIED_TO_USSD, "CODE_DIAL_VIDEO_MODIFIED_TO_USSD");
+ sImsCodeMap.put(CODE_SIP_REDIRECTED, "CODE_SIP_REDIRECTED");
+ sImsCodeMap.put(CODE_SIP_BAD_REQUEST, "CODE_SIP_BAD_REQUEST");
+ sImsCodeMap.put(CODE_SIP_FORBIDDEN, "CODE_SIP_FORBIDDEN");
+ sImsCodeMap.put(CODE_SIP_NOT_FOUND, "CODE_SIP_NOT_FOUND");
+ sImsCodeMap.put(CODE_SIP_NOT_SUPPORTED, "CODE_SIP_NOT_SUPPORTED");
+ sImsCodeMap.put(CODE_SIP_REQUEST_TIMEOUT, "CODE_SIP_REQUEST_TIMEOUT");
+ sImsCodeMap.put(CODE_SIP_TEMPRARILY_UNAVAILABLE, "CODE_SIP_TEMPRARILY_UNAVAILABLE");
+ sImsCodeMap.put(CODE_SIP_BAD_ADDRESS, "CODE_SIP_BAD_ADDRESS");
+ sImsCodeMap.put(CODE_SIP_BUSY, "CODE_SIP_BUSY");
+ sImsCodeMap.put(CODE_SIP_REQUEST_CANCELLED, "CODE_SIP_REQUEST_CANCELLED");
+ sImsCodeMap.put(CODE_SIP_NOT_ACCEPTABLE, "CODE_SIP_NOT_ACCEPTABLE");
+ sImsCodeMap.put(CODE_SIP_NOT_REACHABLE, "CODE_SIP_NOT_REACHABLE");
+ sImsCodeMap.put(CODE_SIP_CLIENT_ERROR, "CODE_SIP_CLIENT_ERROR");
+ sImsCodeMap.put(CODE_SIP_TRANSACTION_DOES_NOT_EXIST, "CODE_SIP_TRANSACTION_DOES_NOT_EXIST");
+ sImsCodeMap.put(CODE_SIP_SERVER_INTERNAL_ERROR, "CODE_SIP_SERVER_INTERNAL_ERROR");
+ sImsCodeMap.put(CODE_SIP_SERVICE_UNAVAILABLE, "CODE_SIP_SERVICE_UNAVAILABLE");
+ sImsCodeMap.put(CODE_SIP_SERVER_TIMEOUT, "CODE_SIP_SERVER_TIMEOUT");
+ sImsCodeMap.put(CODE_SIP_SERVER_ERROR, "CODE_SIP_SERVER_ERROR");
+ sImsCodeMap.put(CODE_SIP_USER_REJECTED, "CODE_SIP_USER_REJECTED");
+ sImsCodeMap.put(CODE_SIP_GLOBAL_ERROR, "CODE_SIP_GLOBAL_ERROR");
+ sImsCodeMap.put(CODE_EMERGENCY_TEMP_FAILURE, "CODE_EMERGENCY_TEMP_FAILURE");
+ sImsCodeMap.put(CODE_EMERGENCY_PERM_FAILURE, "CODE_EMERGENCY_PERM_FAILURE");
+ sImsCodeMap.put(CODE_SIP_USER_MARKED_UNWANTED, "CODE_SIP_USER_MARKED_UNWANTED");
+ sImsCodeMap.put(CODE_SIP_METHOD_NOT_ALLOWED, "CODE_SIP_METHOD_NOT_ALLOWED");
+ sImsCodeMap.put(CODE_SIP_PROXY_AUTHENTICATION_REQUIRED,
+ "CODE_SIP_PROXY_AUTHENTICATION_REQUIRED");
+ sImsCodeMap.put(CODE_SIP_REQUEST_ENTITY_TOO_LARGE, "CODE_SIP_REQUEST_ENTITY_TOO_LARGE");
+ sImsCodeMap.put(CODE_SIP_REQUEST_URI_TOO_LARGE, "CODE_SIP_REQUEST_URI_TOO_LARGE");
+ sImsCodeMap.put(CODE_SIP_EXTENSION_REQUIRED, "CODE_SIP_EXTENSION_REQUIRED");
+ sImsCodeMap.put(CODE_SIP_INTERVAL_TOO_BRIEF, "CODE_SIP_INTERVAL_TOO_BRIEF");
+ sImsCodeMap.put(CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST,
+ "CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST");
+ sImsCodeMap.put(CODE_SIP_LOOP_DETECTED, "CODE_SIP_LOOP_DETECTED");
+ sImsCodeMap.put(CODE_SIP_TOO_MANY_HOPS, "CODE_SIP_TOO_MANY_HOPS");
+ sImsCodeMap.put(CODE_SIP_AMBIGUOUS, "CODE_SIP_AMBIGUOUS");
+ sImsCodeMap.put(CODE_SIP_REQUEST_PENDING, "CODE_SIP_REQUEST_PENDING");
+ sImsCodeMap.put(CODE_SIP_UNDECIPHERABLE, "CODE_SIP_UNDECIPHERABLE");
+ sImsCodeMap.put(CODE_MEDIA_INIT_FAILED, "CODE_MEDIA_INIT_FAILED");
+ sImsCodeMap.put(CODE_MEDIA_NO_DATA, "CODE_MEDIA_NO_DATA");
+ sImsCodeMap.put(CODE_MEDIA_NOT_ACCEPTABLE, "CODE_MEDIA_NOT_ACCEPTABLE");
+ sImsCodeMap.put(CODE_MEDIA_UNSPECIFIED, "CODE_MEDIA_UNSPECIFIED");
+ sImsCodeMap.put(CODE_USER_TERMINATED, "CODE_USER_TERMINATED");
+ sImsCodeMap.put(CODE_USER_NOANSWER, "CODE_USER_NOANSWER");
+ sImsCodeMap.put(CODE_USER_IGNORE, "CODE_USER_IGNORE");
+ sImsCodeMap.put(CODE_USER_DECLINE, "CODE_USER_DECLINE");
+ sImsCodeMap.put(CODE_LOW_BATTERY, "CODE_LOW_BATTERY");
+ sImsCodeMap.put(CODE_BLACKLISTED_CALL_ID, "CODE_BLACKLISTED_CALL_ID");
+ sImsCodeMap.put(CODE_USER_TERMINATED_BY_REMOTE, "CODE_USER_TERMINATED_BY_REMOTE");
+ sImsCodeMap.put(CODE_USER_REJECTED_SESSION_MODIFICATION,
+ "CODE_USER_REJECTED_SESSION_MODIFICATION");
+ sImsCodeMap.put(CODE_USER_CANCELLED_SESSION_MODIFICATION,
+ "CODE_USER_CANCELLED_SESSION_MODIFICATION");
+ sImsCodeMap.put(CODE_SESSION_MODIFICATION_FAILED, "CODE_SESSION_MODIFICATION_FAILED");
+ sImsCodeMap.put(CODE_UT_NOT_SUPPORTED, "CODE_UT_NOT_SUPPORTED");
+ sImsCodeMap.put(CODE_UT_SERVICE_UNAVAILABLE, "CODE_UT_SERVICE_UNAVAILABLE");
+ sImsCodeMap.put(CODE_UT_OPERATION_NOT_ALLOWED, "CODE_UT_OPERATION_NOT_ALLOWED");
+ sImsCodeMap.put(CODE_UT_NETWORK_ERROR, "CODE_UT_NETWORK_ERROR");
+ sImsCodeMap.put(CODE_UT_CB_PASSWORD_MISMATCH, "CODE_UT_CB_PASSWORD_MISMATCH");
+ sImsCodeMap.put(CODE_UT_SS_MODIFIED_TO_DIAL, "CODE_UT_SS_MODIFIED_TO_DIAL");
+ sImsCodeMap.put(CODE_UT_SS_MODIFIED_TO_USSD, "CODE_UT_SS_MODIFIED_TO_USSD");
+ sImsCodeMap.put(CODE_UT_SS_MODIFIED_TO_SS, "CODE_UT_SS_MODIFIED_TO_SS");
+ sImsCodeMap.put(CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO, "CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO");
+ sImsCodeMap.put(CODE_ECBM_NOT_SUPPORTED, "CODE_ECBM_NOT_SUPPORTED");
+ sImsCodeMap.put(CODE_MULTIENDPOINT_NOT_SUPPORTED, "CODE_MULTIENDPOINT_NOT_SUPPORTED");
+ sImsCodeMap.put(CODE_REGISTRATION_ERROR, "CODE_REGISTRATION_ERROR");
+ sImsCodeMap.put(CODE_ANSWERED_ELSEWHERE, "CODE_ANSWERED_ELSEWHERE");
+ sImsCodeMap.put(CODE_CALL_PULL_OUT_OF_SYNC, "CODE_CALL_PULL_OUT_OF_SYNC");
+ sImsCodeMap.put(CODE_CALL_END_CAUSE_CALL_PULL, "CODE_CALL_END_CAUSE_CALL_PULL");
+ sImsCodeMap.put(CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE,
+ "CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE");
+ sImsCodeMap.put(CODE_REJECTED_ELSEWHERE, "CODE_REJECTED_ELSEWHERE");
+ sImsCodeMap.put(CODE_SUPP_SVC_FAILED, "CODE_SUPP_SVC_FAILED");
+ sImsCodeMap.put(CODE_SUPP_SVC_CANCELLED, "CODE_SUPP_SVC_CANCELLED");
+ sImsCodeMap.put(CODE_SUPP_SVC_REINVITE_COLLISION, "CODE_SUPP_SVC_REINVITE_COLLISION");
+ sImsCodeMap.put(CODE_IWLAN_DPD_FAILURE, "CODE_IWLAN_DPD_FAILURE");
+ sImsCodeMap.put(CODE_EPDG_TUNNEL_ESTABLISH_FAILURE, "CODE_EPDG_TUNNEL_ESTABLISH_FAILURE");
+ sImsCodeMap.put(CODE_EPDG_TUNNEL_REKEY_FAILURE, "CODE_EPDG_TUNNEL_REKEY_FAILURE");
+ sImsCodeMap.put(CODE_EPDG_TUNNEL_LOST_CONNECTION, "CODE_EPDG_TUNNEL_LOST_CONNECTION");
+ sImsCodeMap.put(CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED,
+ "CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED");
+ sImsCodeMap.put(CODE_REMOTE_CALL_DECLINE, "CODE_REMOTE_CALL_DECLINE");
+ sImsCodeMap.put(CODE_DATA_LIMIT_REACHED, "CODE_DATA_LIMIT_REACHED");
+ sImsCodeMap.put(CODE_DATA_DISABLED, "CODE_DATA_DISABLED");
+ sImsCodeMap.put(CODE_WIFI_LOST, "CODE_WIFI_LOST");
+ sImsCodeMap.put(CODE_IKEV2_AUTH_FAILURE, "CODE_IKEV2_AUTH_FAILURE");
+ sImsCodeMap.put(CODE_RADIO_OFF, "CODE_RADIO_OFF");
+ sImsCodeMap.put(CODE_NO_VALID_SIM, "CODE_NO_VALID_SIM");
+ sImsCodeMap.put(CODE_RADIO_INTERNAL_ERROR, "CODE_RADIO_INTERNAL_ERROR");
+ sImsCodeMap.put(CODE_NETWORK_RESP_TIMEOUT, "CODE_NETWORK_RESP_TIMEOUT");
+ sImsCodeMap.put(CODE_NETWORK_REJECT, "CODE_NETWORK_REJECT");
+ sImsCodeMap.put(CODE_RADIO_ACCESS_FAILURE, "CODE_RADIO_ACCESS_FAILURE");
+ sImsCodeMap.put(CODE_RADIO_LINK_FAILURE, "CODE_RADIO_LINK_FAILURE");
+ sImsCodeMap.put(CODE_RADIO_LINK_LOST, "CODE_RADIO_LINK_LOST");
+ sImsCodeMap.put(CODE_RADIO_UPLINK_FAILURE, "CODE_RADIO_UPLINK_FAILURE");
+ sImsCodeMap.put(CODE_RADIO_SETUP_FAILURE, "CODE_RADIO_SETUP_FAILURE");
+ sImsCodeMap.put(CODE_RADIO_RELEASE_NORMAL, "CODE_RADIO_RELEASE_NORMAL");
+ sImsCodeMap.put(CODE_RADIO_RELEASE_ABNORMAL, "CODE_RADIO_RELEASE_ABNORMAL");
+ sImsCodeMap.put(CODE_ACCESS_CLASS_BLOCKED, "CODE_ACCESS_CLASS_BLOCKED");
+ sImsCodeMap.put(CODE_NETWORK_DETACH, "CODE_NETWORK_DETACH");
+ sImsCodeMap.put(CODE_SIP_ALTERNATE_EMERGENCY_CALL, "CODE_SIP_ALTERNATE_EMERGENCY_CALL");
+ sImsCodeMap.put(CODE_UNOBTAINABLE_NUMBER, "CODE_UNOBTAINABLE_NUMBER");
+ sImsCodeMap.put(CODE_NO_CSFB_IN_CS_ROAM, "CODE_NO_CSFB_IN_CS_ROAM");
+ sImsCodeMap.put(CODE_REJECT_UNKNOWN, "CODE_REJECT_UNKNOWN");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_CALL_WAITING_DISABLED,
+ "CODE_REJECT_ONGOING_CALL_WAITING_DISABLED");
+ sImsCodeMap.put(CODE_REJECT_CALL_ON_OTHER_SUB, "CODE_REJECT_CALL_ON_OTHER_SUB");
+ sImsCodeMap.put(CODE_REJECT_1X_COLLISION, "CODE_REJECT_1X_COLLISION");
+ sImsCodeMap.put(CODE_REJECT_SERVICE_NOT_REGISTERED, "CODE_REJECT_SERVICE_NOT_REGISTERED");
+ sImsCodeMap.put(CODE_REJECT_CALL_TYPE_NOT_ALLOWED, "CODE_REJECT_CALL_TYPE_NOT_ALLOWED");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_E911_CALL, "CODE_REJECT_ONGOING_E911_CALL");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_CALL_SETUP, "CODE_REJECT_ONGOING_CALL_SETUP");
+ sImsCodeMap.put(CODE_REJECT_MAX_CALL_LIMIT_REACHED, "CODE_REJECT_MAX_CALL_LIMIT_REACHED");
+ sImsCodeMap.put(CODE_REJECT_UNSUPPORTED_SIP_HEADERS, "CODE_REJECT_UNSUPPORTED_SIP_HEADERS");
+ sImsCodeMap.put(CODE_REJECT_UNSUPPORTED_SDP_HEADERS, "CODE_REJECT_UNSUPPORTED_SDP_HEADERS");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_CALL_TRANSFER, "CODE_REJECT_ONGOING_CALL_TRANSFER");
+ sImsCodeMap.put(CODE_REJECT_INTERNAL_ERROR, "CODE_REJECT_INTERNAL_ERROR");
+ sImsCodeMap.put(CODE_REJECT_QOS_FAILURE, "CODE_REJECT_QOS_FAILURE");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_HANDOVER, "CODE_REJECT_ONGOING_HANDOVER");
+ sImsCodeMap.put(CODE_REJECT_VT_TTY_NOT_ALLOWED, "CODE_REJECT_VT_TTY_NOT_ALLOWED");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_CALL_UPGRADE, "CODE_REJECT_ONGOING_CALL_UPGRADE");
+ sImsCodeMap.put(CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED,
+ "CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_CONFERENCE_CALL, "CODE_REJECT_ONGOING_CONFERENCE_CALL");
+ sImsCodeMap.put(CODE_REJECT_VT_AVPF_NOT_ALLOWED, "CODE_REJECT_VT_AVPF_NOT_ALLOWED");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_ENCRYPTED_CALL, "CODE_REJECT_ONGOING_ENCRYPTED_CALL");
+ sImsCodeMap.put(CODE_REJECT_ONGOING_CS_CALL, "CODE_REJECT_ONGOING_CS_CALL");
+ sImsCodeMap.put(CODE_RETRY_ON_IMS_WITHOUT_RTT, "CODE_RETRY_ON_IMS_WITHOUT_RTT");
+ sImsCodeMap.put(CODE_OEM_CAUSE_1, "CODE_OEM_CAUSE_1");
+ sImsCodeMap.put(CODE_OEM_CAUSE_2, "CODE_OEM_CAUSE_2");
+ sImsCodeMap.put(CODE_OEM_CAUSE_3, "CODE_OEM_CAUSE_3");
+ sImsCodeMap.put(CODE_OEM_CAUSE_4, "CODE_OEM_CAUSE_4");
+ sImsCodeMap.put(CODE_OEM_CAUSE_5, "CODE_OEM_CAUSE_5");
+ sImsCodeMap.put(CODE_OEM_CAUSE_6, "CODE_OEM_CAUSE_6");
+ sImsCodeMap.put(CODE_OEM_CAUSE_7, "CODE_OEM_CAUSE_7");
+ sImsCodeMap.put(CODE_OEM_CAUSE_8, "CODE_OEM_CAUSE_8");
+ sImsCodeMap.put(CODE_OEM_CAUSE_9, "CODE_OEM_CAUSE_9");
+ sImsCodeMap.put(CODE_OEM_CAUSE_10, "CODE_OEM_CAUSE_10");
+ sImsCodeMap.put(CODE_OEM_CAUSE_11, "CODE_OEM_CAUSE_11");
+ sImsCodeMap.put(CODE_OEM_CAUSE_12, "CODE_OEM_CAUSE_12");
+ sImsCodeMap.put(CODE_OEM_CAUSE_13, "CODE_OEM_CAUSE_13");
+ sImsCodeMap.put(CODE_OEM_CAUSE_14, "CODE_OEM_CAUSE_14");
+ sImsCodeMap.put(CODE_OEM_CAUSE_15, "CODE_OEM_CAUSE_15");
+ }
+
/**
* Network string error messages.
* mExtraMessage may have these values.
@@ -1203,7 +1394,9 @@ public final class ImsReasonInfo implements Parcelable {
@NonNull
@Override
public String toString() {
- return "ImsReasonInfo :: {" + mCode + ", " + mExtraCode + ", " + mExtraMessage + "}";
+ String imsCode = (sImsCodeMap.containsKey(mCode)) ? sImsCodeMap.get(mCode) : "UNKNOWN_CODE";
+ return "ImsReasonInfo :: {" + mCode + " : " + imsCode + ", "
+ + mExtraCode + ", " + mExtraMessage + "}";
}
@Override
diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java
index aae6f9214c70..0c7264697cd3 100644
--- a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java
@@ -89,7 +89,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived. Synchronous blocking call.
+ * from which the main value is derived. Synchronous blocking call.
*
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
* @param value in Integer format.
@@ -102,7 +102,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived. Synchronous blocking call.
+ * from which the main value is derived. Synchronous blocking call.
*
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
* @param value in String format.
@@ -114,7 +114,7 @@ public class ImsConfigImplBase {
/**
* Gets the value of the specified IMS feature item for specified network type.
- * This operation gets the feature config value from the master storage (i.e. final
+ * This operation gets the feature config value from the main storage (i.e. final
* value). Asynchronous non-blocking call.
*
* @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
@@ -127,7 +127,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS feature item for specified network type.
- * This operation stores the user setting in setting db from which master db
+ * This operation stores the user setting in setting db from which main db
* is derived.
*
* @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
@@ -268,7 +268,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived, and write it into local cache.
+ * from which the main value is derived, and write it into local cache.
* Synchronous blocking call.
*
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
@@ -292,7 +292,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived, and write it into local cache.
+ * from which the main value is derived, and write it into local cache.
* Synchronous blocking call.
*
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
index 73ba0e393e78..8f738d216cbe 100644
--- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
@@ -439,8 +439,8 @@ public class ImsCallSessionImplBase implements AutoCloseable {
* Transfer an established call to given number
*
* @param number number to transfer the call
- * @param isConfirmationRequired if {@code True}, indicates Assured transfer,
- * if {@code False} it indicates Blind transfer.
+ * @param isConfirmationRequired if {@code True}, indicates a confirmed transfer,
+ * if {@code False} it indicates an unconfirmed transfer.
* @hide
*/
public void transfer(@NonNull String number, boolean isConfirmationRequired) {
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 6a2638bc7221..4ef44d3ec9ef 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -142,7 +142,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived, and write it into local cache.
+ * from which the main value is derived, and write it into local cache.
* Synchronous blocking call.
*
* @param item integer key
@@ -167,7 +167,7 @@ public class ImsConfigImplBase {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived, and write it into local cache.
+ * from which the main value is derived, and write it into local cache.
* Synchronous blocking call.
*
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
diff --git a/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java b/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java
index 689becd7169a..17adede86c51 100644
--- a/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java
+++ b/telephony/java/android/telephony/mbms/MbmsTempFileProvider.java
@@ -91,7 +91,7 @@ public class MbmsTempFileProvider extends ContentProvider {
public void attachInfo(Context context, ProviderInfo info) {
super.attachInfo(context, info);
- // Sanity check our security
+ // Correctness check our security
if (info.exported) {
throw new SecurityException("Provider must not be exported");
}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
index 0466efc2f6c6..ab14e82b7087 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
@@ -153,8 +153,8 @@ interface IImsCallSession {
* Transfer an established call to given number
*
* @param number number to transfer the call
- * @param isConfirmationRequired if {@code True}, indicates Assured transfer,
- * if {@code False} it indicates Blind transfer.
+ * @param isConfirmationRequired if {@code True}, indicates a confirmed transfer,
+ * if {@code False} it indicates an unconfirmed transfer.
*/
void transfer(String number, boolean isConfirmationRequired);
diff --git a/telephony/java/com/android/ims/internal/IImsConfig.aidl b/telephony/java/com/android/ims/internal/IImsConfig.aidl
index 7324814ae5a4..1a14e8780664 100644
--- a/telephony/java/com/android/ims/internal/IImsConfig.aidl
+++ b/telephony/java/com/android/ims/internal/IImsConfig.aidl
@@ -49,7 +49,7 @@ interface IImsConfig {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived. Synchronous blocking call.
+ * from which the main value is derived. Synchronous blocking call.
*
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
* @param value in Integer format.
@@ -60,7 +60,7 @@ interface IImsConfig {
/**
* Sets the value for IMS service/capabilities parameters by the operator device
* management entity. It sets the config item value in the provisioned storage
- * from which the master value is derived. Synchronous blocking call.
+ * from which the main value is derived. Synchronous blocking call.
*
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
* @param value in String format.
@@ -70,7 +70,7 @@ interface IImsConfig {
/**
* Gets the value of the specified IMS feature item for specified network type.
- * This operation gets the feature config value from the master storage (i.e. final
+ * This operation gets the feature config value from the main storage (i.e. final
* value). Asynchronous non-blocking call.
*
* @param feature. as defined in com.android.ims.ImsConfig#FeatureConstants.
@@ -82,7 +82,7 @@ interface IImsConfig {
/**
* Sets the value for IMS feature item for specified network type.
- * This operation stores the user setting in setting db from which master db
+ * This operation stores the user setting in setting db from which main db
* is dervied.
*
* @param feature. as defined in com.android.ims.ImsConfig#FeatureConstants.
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 542e08d743ab..a34e474e666e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -479,7 +479,7 @@ public class SmsMessage extends SmsMessageBase {
length = dis.readUnsignedByte();
addr.numberOfDigits = length;
- // sanity check on the length
+ // Correctness check on the length
if (length > pdu.length) {
throw new RuntimeException(
"createFromPdu: Invalid pdu, addr.numberOfDigits " + length
@@ -496,7 +496,7 @@ public class SmsMessage extends SmsMessageBase {
//encoded BearerData:
bearerDataLength = dis.readInt();
- // sanity check on the length
+ // Correctness check on the length
if (bearerDataLength > pdu.length) {
throw new RuntimeException(
"createFromPdu: Invalid pdu, bearerDataLength " + bearerDataLength
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 7e31c4633050..e3df903b7f4f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -353,7 +353,7 @@ public class SmsMessage extends SmsMessageBase {
statusReportRequested, ret);
// Skip encoding pdu if error occurs when create pdu head and the error will be handled
- // properly later on encodedMessage sanity check.
+ // properly later on encodedMessage correctness check.
if (bo == null) return ret;
// User Data (and length)
@@ -535,7 +535,7 @@ public class SmsMessage extends SmsMessageBase {
scAddress, destinationAddress, (byte) 0x41, /* TP-MTI=SMS-SUBMIT, TP-UDHI=true */
statusReportRequested, ret);
// Skip encoding pdu if error occurs when create pdu head and the error will be handled
- // properly later on encodedMessage sanity check.
+ // properly later on encodedMessage correctness check.
if (bo == null) return ret;
// TP-Data-Coding-Scheme
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java
index 2df0024bdea9..56db4f98e160 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java
@@ -35,7 +35,7 @@ import java.security.MessageDigest;
import java.util.Random;
import java.util.concurrent.TimeUnit;
-public class DummyBlobData {
+public class FakeBlobData {
private static final long DEFAULT_SIZE_BYTES = 10 * 1024L * 1024L;
private final Random mRandom;
@@ -47,7 +47,7 @@ public class DummyBlobData {
byte[] mFileDigest;
long mExpiryTimeMs;
- private DummyBlobData(Builder builder) {
+ private FakeBlobData(Builder builder) {
mRandom = new Random(builder.getRandomSeed());
mFile = new File(builder.getContext().getFilesDir(), builder.getFileName());
mFileSize = builder.getFileSize();
@@ -116,8 +116,8 @@ public class DummyBlobData {
return mExpiryDurationMs;
}
- public DummyBlobData build() {
- return new DummyBlobData(this);
+ public FakeBlobData build() {
+ return new FakeBlobData(this);
}
}
diff --git a/tests/BootImageProfileTest/OWNERS b/tests/BootImageProfileTest/OWNERS
index 657b3f2add2e..7ee0d9a5e77e 100644
--- a/tests/BootImageProfileTest/OWNERS
+++ b/tests/BootImageProfileTest/OWNERS
@@ -1,4 +1,4 @@
-mathieuc@google.com
calin@google.com
+mathieuc@google.com
+ngeoffray@google.com
yawanng@google.com
-sehr@google.com
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index dcabce896ce2..c1a3ed695096 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker
+import com.android.server.wm.flicker.dsl.EventLogAssertion
import com.android.server.wm.flicker.dsl.LayersAssertion
import com.android.server.wm.flicker.dsl.WmAssertion
import com.android.server.wm.flicker.helpers.WindowUtils
@@ -53,19 +54,19 @@ fun LayersAssertion.noUncoveredRegions(
if (allStates) {
all("noUncoveredRegions", enabled, bugId) {
if (startingBounds == endingBounds) {
- this.coversRegion(startingBounds)
+ this.coversAtLeastRegion(startingBounds)
} else {
- this.coversRegion(startingBounds)
+ this.coversAtLeastRegion(startingBounds)
.then()
- .coversRegion(endingBounds)
+ .coversAtLeastRegion(endingBounds)
}
}
} else {
start("noUncoveredRegions_StartingPos") {
- this.coversRegion(startingBounds)
+ this.coversAtLeastRegion(startingBounds)
}
end("noUncoveredRegions_EndingPos") {
- this.coversRegion(endingBounds)
+ this.coversAtLeastRegion(endingBounds)
}
}
}
@@ -130,4 +131,23 @@ fun LayersAssertion.statusBarLayerRotatesScales(
end("statusBarLayerRotatesScales_EndingPos", enabled, bugId) {
this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, endingPos)
}
+}
+
+fun EventLogAssertion.focusChanges(
+ vararg windows: String,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all(enabled = enabled, bugId = bugId) {
+ this.focusChanges(windows)
+ }
+}
+
+fun EventLogAssertion.focusDoesNotChange(
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ all(enabled = enabled, bugId = bugId) {
+ this.focusDoesNotChange()
+ }
} \ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
index eaf4d8799208..abe7dbc57002 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
@@ -92,7 +92,7 @@ abstract class FlickerTestBase {
app2: IAppHelper?,
extraInfo: String
): String {
- var testTag = "${testName}__$${app.launcherName}"
+ var testTag = "${testName}__${app.launcherName}"
if (app2 != null) {
testTag += "-${app2.launcherName}"
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index 31d1fd313374..2e4d390ceb60 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -81,11 +81,11 @@ class CloseImeAutoOpenWindowToHomeTest(
}
layersTrace {
- navBarLayerIsAlwaysVisible()
- statusBarLayerIsAlwaysVisible()
- noUncoveredRegions(rotation)
- navBarLayerRotatesAndScales(rotation)
- statusBarLayerRotatesScales(rotation)
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
+ navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+ statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
imeLayerBecomesInvisible(bugId = 141458352)
imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index b643ec2ba332..1c0da4f920bb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -89,9 +89,9 @@ open class CloseImeWindowToHomeTest(
}
layersTrace {
- navBarLayerIsAlwaysVisible()
- statusBarLayerIsAlwaysVisible()
- noUncoveredRegions(rotation)
+ navBarLayerIsAlwaysVisible(bugId = 140855415)
+ statusBarLayerIsAlwaysVisible(bugId = 140855415)
+ noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
imeLayerBecomesInvisible(bugId = 153739621)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 1240e0da133f..62337e9bff34 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -19,6 +19,7 @@ package com.android.server.wm.flicker.launch
import android.view.Surface
import androidx.test.filters.LargeTest
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusChanges
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
@@ -70,18 +71,22 @@ class OpenAppColdTest(
windowManagerTrace {
navBarWindowIsAlwaysVisible()
statusBarWindowIsAlwaysVisible()
- appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+ appWindowReplacesLauncherAsTopWindow()
wallpaperWindowBecomesInvisible()
}
layersTrace {
- noUncoveredRegions(rotation, bugId = 141361128)
// During testing the launcher is always in portrait mode
+ noUncoveredRegions(Surface.ROTATION_0, rotation, bugId = 141361128)
navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
- navBarLayerIsAlwaysVisible(bugId = 141361128)
- statusBarLayerIsAlwaysVisible(bugId = 141361128)
- wallpaperLayerBecomesInvisible(bugId = 141361128)
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible(enabled = false)
+ wallpaperLayerBecomesInvisible()
+ }
+
+ eventLog {
+ focusChanges("NexusLauncherActivity", testApp.`package`)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
index 3cec077f0184..7d70812a22f2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
@@ -44,10 +44,9 @@ abstract class OpenAppTestBase(
enabled: Boolean = bugId == 0
) {
all("appWindowReplacesLauncherAsTopWindow", enabled, bugId) {
- this.showsAppWindowOnTop(
- "Launcher")
+ this.showsAppWindowOnTop("Launcher")
.then()
- .showsAppWindowOnTop(testApp.getPackage())
+ .showsAppWindowOnTop("Snapshot", testApp.getPackage())
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index 98413a1cbc6b..9a8e37b19e56 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -20,6 +20,7 @@ import android.view.Surface
import androidx.test.filters.LargeTest
import com.android.server.wm.flicker.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusChanges
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
@@ -78,18 +79,22 @@ class OpenAppWarmTest(
windowManagerTrace {
navBarWindowIsAlwaysVisible()
statusBarWindowIsAlwaysVisible()
- appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+ appWindowReplacesLauncherAsTopWindow()
wallpaperWindowBecomesInvisible(enabled = false)
}
layersTrace {
- noUncoveredRegions(rotation, bugId = 141361128)
// During testing the launcher is always in portrait mode
+ noUncoveredRegions(Surface.ROTATION_0, rotation, bugId = 141361128)
navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
- navBarLayerIsAlwaysVisible(bugId = 141361128)
- statusBarLayerIsAlwaysVisible(bugId = 141361128)
- wallpaperLayerBecomesInvisible(bugId = 141361128)
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible(enabled = false)
+ wallpaperLayerBecomesInvisible()
+ }
+
+ eventLog {
+ focusChanges("NexusLauncherActivity", testApp.`package`)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt
new file mode 100644
index 000000000000..4acd97553bc0
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.wm.flicker.pip
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.expandPipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+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.
+ * To run this test: `atest FlickerTests:PipToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+class EnterPipTest(
+ rotationName: String,
+ rotation: Int
+) : PipTestBase(rotationName, rotation) {
+ @Test
+ fun test() {
+ flicker(instrumentation) {
+ withTag { buildTestTag("enterPip", testApp, rotation) }
+ repeat { 1 }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ }
+ eachRun {
+ device.pressHome()
+ testApp.open()
+ this.setRotation(rotation)
+ }
+ }
+ teardown {
+ eachRun {
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ testApp.exit()
+ this.setRotation(Surface.ROTATION_0)
+ }
+ test {
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
+ }
+ }
+ transitions {
+ testApp.clickEnterPipButton(device)
+ device.expandPipWindow()
+ }
+ assertions {
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ all("pipWindowBecomesVisible") {
+ this.showsAppWindow(testApp.`package`)
+ .then()
+ .showsAppWindow(sPipWindowTitle)
+ }
+ }
+
+ layersTrace {
+ navBarLayerIsAlwaysVisible()
+ statusBarLayerIsAlwaysVisible()
+ noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
+ navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+ statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
+
+ all("pipLayerBecomesVisible") {
+ this.showsLayer(testApp.launcherName)
+ .then()
+ .showsLayer(sPipWindowTitle)
+ }
+ }
+ }
+ }
+ }
+
+ 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/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
index 4afabd4cdfb1..691db7fbac5c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
@@ -16,9 +16,7 @@
package com.android.server.wm.flicker.pip
-import com.android.server.wm.flicker.dsl.LayersAssertion
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.dsl.WmAssertion
import com.android.server.wm.flicker.helpers.PipAppHelper
abstract class PipTestBase(
@@ -27,24 +25,6 @@ abstract class PipTestBase(
) : NonRotationTestBase(rotationName, rotation) {
protected val testApp = PipAppHelper(instrumentation)
- protected fun WmAssertion.pipWindowBecomesVisible() {
- all("pipWindowBecomesVisible") {
- this.skipUntilFirstAssertion()
- .showsAppWindowOnTop(sPipWindowTitle)
- .then()
- .hidesAppWindow(sPipWindowTitle)
- }
- }
-
- protected fun LayersAssertion.pipLayerBecomesVisible() {
- all("pipLayerBecomesVisible") {
- this.skipUntilFirstAssertion()
- .showsLayer(sPipWindowTitle)
- .then()
- .hidesLayer(sPipWindowTitle)
- }
- }
-
companion object {
const val sPipWindowTitle = "PipMenuActivity"
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
index e5a73f708fe4..04c2f59118bd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
@@ -20,6 +20,7 @@ import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusChanges
import com.android.server.wm.flicker.helpers.closePipWindow
import com.android.server.wm.flicker.helpers.expandPipWindow
import com.android.server.wm.flicker.helpers.hasPipWindow
@@ -55,35 +56,42 @@ class PipToAppTest(
withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
repeat { 1 }
setup {
- eachRun {
+ test {
device.wakeUpAndGoToHomeScreen()
+ device.pressHome()
+ testApp.open()
+ }
+ eachRun {
+ this.setRotation(rotation)
+ testApp.clickEnterPipButton(device)
+ device.hasPipWindow()
}
}
teardown {
eachRun {
- testApp.exit()
this.setRotation(Surface.ROTATION_0)
}
test {
if (device.hasPipWindow()) {
device.closePipWindow()
}
+ testApp.exit()
}
}
transitions {
- device.pressHome()
- this.setRotation(rotation)
- testApp.open()
- testApp.clickEnterPipButton(device)
device.expandPipWindow()
device.waitForIdle()
- testApp.exit()
}
assertions {
windowManagerTrace {
navBarWindowIsAlwaysVisible()
statusBarWindowIsAlwaysVisible()
- pipWindowBecomesVisible()
+
+ all("appReplacesPipWindow") {
+ this.showsAppWindow(sPipWindowTitle)
+ .then()
+ .showsAppWindowOnTop(testApp.launcherName)
+ }
}
layersTrace {
@@ -92,9 +100,20 @@ class PipToAppTest(
noUncoveredRegions(rotation)
navBarLayerRotatesAndScales(rotation)
statusBarLayerRotatesScales(rotation)
- pipLayerBecomesVisible()
+
+ all("appReplacesPipLayer") {
+ this.showsLayer(sPipWindowTitle)
+ .then()
+ .showsLayer(testApp.launcherName)
+ }
+ }
+
+ eventLog {
+ focusChanges(
+ "NexusLauncherActivity", testApp.launcherName, "NexusLauncherActivity",
+ bugId = 151179149)
}
}
}
}
-} \ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
index f6d9ce261f60..b6074cd7033b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
@@ -20,6 +20,7 @@ import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusChanges
import com.android.server.wm.flicker.helpers.closePipWindow
import com.android.server.wm.flicker.helpers.hasPipWindow
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
@@ -54,54 +55,74 @@ class PipToHomeTest(
withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
repeat { 1 }
setup {
- eachRun {
+ test {
device.wakeUpAndGoToHomeScreen()
device.pressHome()
- this.setRotation(rotation)
+ }
+ eachRun {
testApp.open()
+ this.setRotation(rotation)
+ testApp.clickEnterPipButton(device)
+ device.hasPipWindow()
}
}
teardown {
eachRun {
- testApp.exit()
this.setRotation(Surface.ROTATION_0)
+ if (device.hasPipWindow()) {
+ device.closePipWindow()
+ }
}
test {
if (device.hasPipWindow()) {
device.closePipWindow()
}
+ testApp.exit()
}
}
transitions {
- testApp.clickEnterPipButton(device)
testApp.closePipWindow(device)
- device.waitForIdle()
- testApp.exit()
}
assertions {
windowManagerTrace {
navBarWindowIsAlwaysVisible()
statusBarWindowIsAlwaysVisible()
- pipWindowBecomesVisible()
- all {
- this.showsAppWindowOnTop(sPipWindowTitle)
- .and()
- .showsBelowAppWindow("Wallpaper")
+ all("pipWindowBecomesInvisible") {
+ this.showsAppWindow(sPipWindowTitle)
.then()
- .showsAboveAppWindow("Wallpaper")
+ .hidesAppWindow(sPipWindowTitle)
}
}
layersTrace {
navBarLayerIsAlwaysVisible()
statusBarLayerIsAlwaysVisible()
- noUncoveredRegions(rotation)
+ // The final state is the launcher, so always in portrait mode
+ noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
navBarLayerRotatesAndScales(rotation)
statusBarLayerRotatesScales(rotation)
- pipLayerBecomesVisible()
+
+ all("pipLayerBecomesInvisible") {
+ this.showsLayer(sPipWindowTitle)
+ .then()
+ .hidesLayer(sPipWindowTitle)
+ }
+ }
+
+ eventLog {
+ focusChanges(testApp.launcherName, "NexusLauncherActivity", bugId = 151179149)
}
}
}
}
+
+ 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/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 239c08204209..5e75e4a144bf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -22,6 +22,7 @@ import com.android.server.wm.flicker.NonRotationTestBase.Companion.SCREENSHOT_LA
import com.android.server.wm.flicker.RotationTestBase
import com.android.server.wm.flicker.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
@@ -61,25 +62,29 @@ class ChangeAppRotationTest(
}
repeat { 1 }
setup {
- eachRun {
+ test {
device.wakeUpAndGoToHomeScreen()
testApp.open()
+ }
+ eachRun {
this.setRotation(beginRotation)
}
}
teardown {
eachRun {
- testApp.exit()
this.setRotation(Surface.ROTATION_0)
}
+ test {
+ testApp.exit()
+ }
}
transitions {
this.setRotation(endRotation)
}
assertions {
windowManagerTrace {
- navBarWindowIsAlwaysVisible(bugId = 140855415)
- statusBarWindowIsAlwaysVisible(bugId = 140855415)
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
}
layersTrace {
@@ -102,23 +107,18 @@ class ChangeAppRotationTest(
this.hasVisibleRegion(testApp.getPackage(), endingPos)
}
- all("screenshotLayerBecomesInvisible", enabled = false) {
+ all("screenshotLayerBecomesInvisible") {
this.showsLayer(testApp.getPackage())
.then()
- .replaceVisibleLayer(
- testApp.getPackage(),
- SCREENSHOT_LAYER)
- .then()
- .showsLayer(testApp.getPackage())
- .and()
.showsLayer(SCREENSHOT_LAYER)
.then()
- .replaceVisibleLayer(
- SCREENSHOT_LAYER,
- testApp.getPackage()
- )
+ showsLayer(testApp.getPackage())
}
}
+
+ eventLog {
+ focusDoesNotChange(bugId = 151179149)
+ }
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 4746376b724d..de87b412fc90 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -24,6 +24,8 @@ import androidx.test.filters.LargeTest
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.RotationTestBase
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.stopPackage
@@ -128,14 +130,18 @@ class SeamlessAppRotationTest(
val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
val endingBounds = WindowUtils.getDisplayBounds(endRotation)
if (startingBounds == endingBounds) {
- this.coversRegion(startingBounds)
+ this.coversAtLeastRegion(startingBounds)
} else {
- this.coversRegion(startingBounds)
+ this.coversAtLeastRegion(startingBounds)
.then()
- .coversRegion(endingBounds)
+ .coversAtLeastRegion(endingBounds)
}
}
}
+
+ eventLog {
+ focusDoesNotChange(bugId = 151179149)
+ }
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index 7c196961e8fd..e078f266e5ed 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -16,13 +16,14 @@
package com.android.server.wm.flicker.splitscreen
-import android.os.SystemClock
import android.view.Surface
import androidx.test.filters.LargeTest
import com.android.server.wm.flicker.NonRotationTestBase
import com.android.server.wm.flicker.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusChanges
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.server.wm.flicker.navBarLayerIsAlwaysVisible
@@ -58,16 +59,21 @@ class OpenAppToSplitScreenTest(
withTag { buildTestTag("appToSplitScreen", testApp, rotation) }
repeat { 1 }
setup {
- eachRun {
+ test {
device.wakeUpAndGoToHomeScreen()
- this.setRotation(rotation)
+ }
+ eachRun {
testApp.open()
- SystemClock.sleep(500)
+ this.setRotation(rotation)
}
}
teardown {
eachRun {
- device.exitSplitScreen()
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
+ }
+ }
+ test {
testApp.exit()
}
}
@@ -93,6 +99,11 @@ class OpenAppToSplitScreenTest(
.showsLayer(DOCKED_STACK_DIVIDER)
}
}
+
+ eventLog {
+ focusChanges(testApp.`package`,
+ "recents_animation_input_consumer", "NexusLauncherActivity")
+ }
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
index a93330d900fb..a08b2bfdf1fe 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
@@ -19,15 +19,16 @@ package com.android.server.wm.flicker.splitscreen
import android.graphics.Region
import android.util.Rational
import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.LargeTest
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import com.android.server.wm.flicker.FlickerTestBase
import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.ImeAppHelper
+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
@@ -171,6 +172,10 @@ class ResizeSplitScreenTest : FlickerTestBase() {
.hasVisibleRegion(sImeActivity, bottomAppBounds)
}
}
+
+ eventLog {
+ focusDoesNotChange()
+ }
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
index 268ba9ee1193..e2d78399b35b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
@@ -17,11 +17,11 @@
package com.android.server.wm.flicker.splitscreen
import android.view.Surface
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.FlickerTestBase
+import com.android.server.wm.flicker.NonRotationTestBase
import com.android.server.wm.flicker.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.exitSplitScreen
import com.android.server.wm.flicker.helpers.isInSplitScreen
import com.android.server.wm.flicker.helpers.launchSplitScreen
@@ -37,16 +37,19 @@ import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
/**
* Test open app to split screen.
* To run this test: `atest FlickerTests:SplitScreenToLauncherTest`
*/
@LargeTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SplitScreenToLauncherTest : FlickerTestBase() {
- private val rotation: Int = Surface.ROTATION_0
+class SplitScreenToLauncherTest(
+ rotationName: String,
+ rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
@Test
fun test() {
val testApp = StandardAppHelper(instrumentation,
@@ -56,8 +59,10 @@ class SplitScreenToLauncherTest : FlickerTestBase() {
withTag { buildTestTag("splitScreenToLauncher", testApp, rotation) }
repeat { 1 }
setup {
- eachRun {
+ test {
device.wakeUpAndGoToHomeScreen()
+ }
+ eachRun {
testApp.open()
this.setRotation(rotation)
device.launchSplitScreen()
@@ -103,7 +108,21 @@ class SplitScreenToLauncherTest : FlickerTestBase() {
.hidesLayer(testApp.getPackage())
}
}
+
+ eventLog {
+ focusDoesNotChange(bugId = 151179149)
+ }
}
}
}
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ // b/161435597 causes the test not to work on 90 degrees
+ val supportedRotations = intArrayOf(Surface.ROTATION_0)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
}
diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp
new file mode 100644
index 000000000000..c4bfcb1d2261
--- /dev/null
+++ b/tests/LocalizationTest/Android.bp
@@ -0,0 +1,41 @@
+// 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.
+
+android_test {
+ name: "LocalizationTest",
+ srcs: ["java/**/*.kt"],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.ext.junit",
+ "androidx.test.rules",
+ "mockito-target-extended-minus-junit4",
+ "truth-prebuilt",
+ ],
+ jni_libs: [
+ // For mockito extended
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+ certificate: "platform",
+ platform_apis: true,
+ test_suites: ["device-tests"],
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/core/res/res/drawable-car-night/car_dialog_button_background.xml b/tests/LocalizationTest/AndroidManifest.xml
index 138cb38b0d87..b135443960f5 100644
--- a/core/res/res/drawable-car-night/car_dialog_button_background.xml
+++ b/tests/LocalizationTest/AndroidManifest.xml
@@ -14,19 +14,16 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true">
- <ripple android:color="#2371cd">
- <item android:id="@android:id/mask">
- <color android:color="@*android:color/car_white_1000"/>
- </item>
- </ripple>
- </item>
- <item>
- <ripple android:color="?android:attr/colorControlHighlight">
- <item android:id="@android:id/mask">
- <color android:color="@*android:color/car_white_1000"/>
- </item>
- </ripple>
- </item>
-</selector>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.android.internal.app">
+
+ <application android:debuggable="true" android:testOnly="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.android.internal.app"
+ android:label="Localization Tests" />
+
+</manifest>
diff --git a/tests/LocalizationTest/AndroidTest.xml b/tests/LocalizationTest/AndroidTest.xml
new file mode 100644
index 000000000000..8309b4f611f8
--- /dev/null
+++ b/tests/LocalizationTest/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<configuration description="Localization Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="LocalizationTest.apk" />
+ </target_preparer>
+
+ <option name="test-tag" value="LocalizationTest" />
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.android.internal.app" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration> \ No newline at end of file
diff --git a/tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.kt b/tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.kt
new file mode 100644
index 000000000000..22ea97167326
--- /dev/null
+++ b/tests/LocalizationTest/java/com/android/internal/app/LocalizationTest.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.android.internal.app
+
+import android.os.SystemProperties
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.internal.R
+import com.android.internal.app.LocalePicker
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.After
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.MockitoSession
+
+@RunWith(AndroidJUnit4::class)
+class LocalizationTest {
+ private val mContext = InstrumentationRegistry.getInstrumentation().context
+ private val mUnfilteredLocales =
+ mContext.getResources().getStringArray(R.array.supported_locales)
+
+ private lateinit var mMockitoSession: MockitoSession
+
+ @Before
+ fun setUp() {
+ mMockitoSession = mockitoSession()
+ .initMocks(this)
+ .spyStatic(SystemProperties::class.java)
+ .startMocking()
+ }
+
+ @After
+ fun tearDown() {
+ mMockitoSession.finishMocking()
+ }
+
+ @Test
+ fun testGetSupportedLocales_noFilter() {
+ // Filter not set.
+ setTestLocaleFilter(null)
+
+ val locales1 = LocalePicker.getSupportedLocales(mContext)
+
+ assertThat(locales1).isEqualTo(mUnfilteredLocales)
+
+ // Empty filter.
+ setTestLocaleFilter("")
+
+ val locales2 = LocalePicker.getSupportedLocales(mContext)
+
+ assertThat(locales2).isEqualTo(mUnfilteredLocales)
+ }
+
+ @Test
+ fun testGetSupportedLocales_invalidFilter() {
+ setTestLocaleFilter("**")
+
+ val locales = LocalePicker.getSupportedLocales(mContext)
+
+ assertThat(locales).isEqualTo(mUnfilteredLocales)
+ }
+
+ @Test
+ fun testGetSupportedLocales_inclusiveFilter() {
+ setTestLocaleFilter("^(de-AT|de-DE|en|ru).*")
+
+ val locales = LocalePicker.getSupportedLocales(mContext)
+
+ assertThat(locales).isEqualTo(
+ mUnfilteredLocales
+ .filter { it.startsWithAnyOf("de-AT", "de-DE", "en", "ru") }
+ .toTypedArray()
+ )
+ }
+
+ @Test
+ fun testGetSupportedLocales_exclusiveFilter() {
+ setTestLocaleFilter("^(?!de-IT|es|fr).*")
+
+ val locales = LocalePicker.getSupportedLocales(mContext)
+
+ assertThat(locales).isEqualTo(
+ mUnfilteredLocales
+ .filter { !it.startsWithAnyOf("de-IT", "es", "fr") }
+ .toTypedArray()
+ )
+ }
+
+ private fun setTestLocaleFilter(localeFilter: String?) {
+ doReturn(localeFilter).`when` { SystemProperties.get(eq("ro.localization.locale_filter")) }
+ }
+
+ private fun String.startsWithAnyOf(vararg prefixes: String): Boolean {
+ prefixes.forEach {
+ if (startsWith(it)) return true
+ }
+
+ return false
+ }
+}
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index b7c47c2bc223..dd3f5bebdb8e 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -19,23 +19,23 @@ package android.net
import android.app.Instrumentation
import android.content.Context
import android.net.NetworkCapabilities.TRANSPORT_TEST
+import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
+import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
+import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested
import android.os.Build
import android.os.HandlerThread
import android.os.Looper
-import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
-import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested
-import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
import androidx.test.InstrumentationRegistry
-import com.android.testutils.ArrayTrackRecord
+import com.android.net.module.util.ArrayTrackRecord
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
-import java.util.UUID
-import kotlin.test.assertEquals
-import kotlin.test.assertNotEquals
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import java.util.UUID
+import kotlin.test.assertEquals
+import kotlin.test.assertNotEquals
private const val DEFAULT_TIMEOUT_MS = 5000L
private val instrumentation: Instrumentation
diff --git a/tests/net/java/com/android/server/NetIdManagerTest.kt b/tests/net/java/com/android/server/NetIdManagerTest.kt
index 045f89f85e3b..6f5e740d344c 100644
--- a/tests/net/java/com/android/server/NetIdManagerTest.kt
+++ b/tests/net/java/com/android/server/NetIdManagerTest.kt
@@ -19,8 +19,8 @@ package com.android.server
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.server.NetIdManager.MIN_NET_ID
-import com.android.testutils.ExceptionUtils.ThrowingRunnable
import com.android.testutils.assertThrows
+import com.android.testutils.ExceptionUtils.ThrowingRunnable
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index eb0a867d8ec1..a384687e06f6 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -28,6 +28,7 @@ import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.SYSTEM_UID;
import static com.android.server.connectivity.PermissionMonitor.NETWORK;
@@ -138,17 +139,10 @@ public class PermissionMonitorTest {
verify(mMockPmi).getPackageList(mPermissionMonitor);
}
- /**
- * Remove all permissions from the uid then build new package info and setup permissions to uid
- * for checking restricted network permission.
- */
- private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
- String... permissions) {
+ private boolean wouldBeCarryoverPackage(String partition, int targetSdkVersion, int uid) {
final PackageInfo packageInfo = buildPackageInfo(partition, uid, MOCK_USER1);
packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
- removeAllPermissions(uid);
- addPermissions(uid, permissions);
- return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo.applicationInfo);
+ return mPermissionMonitor.isCarryoverPackage(packageInfo.applicationInfo);
}
private static PackageInfo packageInfoWithPartition(String partition) {
@@ -228,61 +222,57 @@ public class PermissionMonitorTest {
assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
}
+ /**
+ * Remove all permissions from the uid then setup permissions to uid for checking restricted
+ * network permission.
+ */
+ private void assertRestrictedNetworkPermission(boolean hasPermission, int uid,
+ String... permissions) {
+ removeAllPermissions(uid);
+ addPermissions(uid, permissions);
+ assertEquals(hasPermission, mPermissionMonitor.hasRestrictedNetworkPermission(uid));
+ }
+
@Test
public void testHasRestrictedNetworkPermission() {
- assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, MOCK_UID1, NETWORK_STACK));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
-
- assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
+ assertRestrictedNetworkPermission(false, MOCK_UID1);
+ assertRestrictedNetworkPermission(false, MOCK_UID1, CHANGE_NETWORK_STATE);
+ assertRestrictedNetworkPermission(true, MOCK_UID1, NETWORK_STACK);
+ assertRestrictedNetworkPermission(false, MOCK_UID1, CONNECTIVITY_INTERNAL);
+ assertRestrictedNetworkPermission(true, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+ assertRestrictedNetworkPermission(false, MOCK_UID1, CHANGE_WIFI_STATE);
+ assertRestrictedNetworkPermission(true, MOCK_UID1, PERMISSION_MAINLINE_NETWORK_STACK);
+
+ assertFalse(mPermissionMonitor.hasRestrictedNetworkPermission(MOCK_UID2));
+ assertFalse(mPermissionMonitor.hasRestrictedNetworkPermission(SYSTEM_UID));
}
@Test
- public void testHasRestrictedNetworkPermissionSystemUid() {
+ public void testIsCarryoverPackage() {
doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
- assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_INTERNAL));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
- assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_INTERNAL));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
- }
-
- @Test
- public void testHasRestrictedNetworkPermissionVendorApp() {
- assertTrue(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_P, MOCK_UID1, NETWORK_STACK));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
-
- assertFalse(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_NETWORK_STATE));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
+ assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
+
+ assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, SYSTEM_UID));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, MOCK_UID1));
+ assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID1));
}
private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
@@ -296,19 +286,23 @@ public class PermissionMonitorTest {
@Test
public void testHasUseBackgroundNetworksPermission() throws Exception {
- doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
- assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
- assertBackgroundPermission(false, "system1", SYSTEM_UID);
- assertBackgroundPermission(false, "system2", SYSTEM_UID, CONNECTIVITY_INTERNAL);
- assertBackgroundPermission(true, "system3", SYSTEM_UID, CHANGE_NETWORK_STATE);
-
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
assertBackgroundPermission(false, "mock1", MOCK_UID1);
- assertBackgroundPermission(true, "mock2", MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+ assertBackgroundPermission(false, "mock2", MOCK_UID1, CONNECTIVITY_INTERNAL);
+ assertBackgroundPermission(true, "mock3", MOCK_UID1, NETWORK_STACK);
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
- assertBackgroundPermission(false, "mock3", MOCK_UID2, CONNECTIVITY_INTERNAL);
- assertBackgroundPermission(true, "mock4", MOCK_UID2, NETWORK_STACK);
+ assertBackgroundPermission(false, "mock4", MOCK_UID2);
+ assertBackgroundPermission(true, "mock5", MOCK_UID2,
+ CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+
+ doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
+ assertBackgroundPermission(false, "system1", SYSTEM_UID);
+ assertBackgroundPermission(true, "system2", SYSTEM_UID, CHANGE_NETWORK_STATE);
+ doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
+ removeAllPermissions(SYSTEM_UID);
+ assertBackgroundPermission(true, "system3", SYSTEM_UID);
}
private class NetdMonitor {
diff --git a/tests/utils/DummyIME/Android.bp b/tests/utils/StubIME/Android.bp
index 4a44b3b27992..668c92c86c51 100644
--- a/tests/utils/DummyIME/Android.bp
+++ b/tests/utils/StubIME/Android.bp
@@ -15,7 +15,7 @@
//
android_test {
- name: "DummyIME",
+ name: "StubIME",
srcs: ["src/**/*.java"],
sdk_version: "current",
}
diff --git a/tests/utils/DummyIME/AndroidManifest.xml b/tests/utils/StubIME/AndroidManifest.xml
index 4dc0b57e1075..bc64c671d9be 100644
--- a/tests/utils/DummyIME/AndroidManifest.xml
+++ b/tests/utils/StubIME/AndroidManifest.xml
@@ -18,20 +18,20 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.testing.dummyime">
+ package="com.android.testing.stubime">
<application android:label="Dummy IME">
<service android:name="DummyIme"
- android:permission="android.permission.BIND_INPUT_METHOD"
- android:exported="true">
+ android:permission="android.permission.BIND_INPUT_METHOD"
+ android:exported="true">
<intent-filter>
<action android:name="android.view.InputMethod"/>
</intent-filter>
<meta-data android:name="android.view.im"
- android:resource="@xml/method"/>
+ android:resource="@xml/method"/>
</service>
<activity android:name=".ImePreferences"
- android:label="Dummy IME Settings"
- android:exported="true">
+ android:label="Stub IME Settings"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
diff --git a/tests/utils/DummyIME/res/xml/method.xml b/tests/utils/StubIME/res/xml/method.xml
index 43a330e2bc93..1bb4bcd3480b 100644
--- a/tests/utils/DummyIME/res/xml/method.xml
+++ b/tests/utils/StubIME/res/xml/method.xml
@@ -21,9 +21,9 @@
<!-- for the Search Manager. -->
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
- android:settingsActivity="com.android.testing.dummyime.ImePreferences">
+ android:settingsActivity="com.android.testing.stubime.ImePreferences">
<subtype
android:label="Generic"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard" />
-</input-method> \ No newline at end of file
+</input-method>
diff --git a/tests/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java b/tests/utils/StubIME/src/com/android/testing/stubime/ImePreferences.java
index 41036ab86596..b77525ad0a43 100644
--- a/tests/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java
+++ b/tests/utils/StubIME/src/com/android/testing/stubime/ImePreferences.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.testing.dummyime;
+package com.android.testing.stubime;
import android.preference.PreferenceActivity;
/**
- * Dummy IME preference activity
+ * Stub IME preference activity
*/
public class ImePreferences extends PreferenceActivity {
diff --git a/tests/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java b/tests/utils/StubIME/src/com/android/testing/stubime/StubIme.java
index 7b7a39a702e5..8795202b3283 100644
--- a/tests/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java
+++ b/tests/utils/StubIME/src/com/android/testing/stubime/StubIme.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.testing.dummyime;
+package com.android.testing.stubime;
import android.inputmethodservice.InputMethodService;
/**
- * Dummy IME implementation that basically does nothing
+ * Stub IME implementation that basically does nothing
*/
-public class DummyIme extends InputMethodService {
+public class StubIme extends InputMethodService {
@Override
public boolean onEvaluateFullscreenMode() {
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 931a14b1f650..3d9be59dd960 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -342,7 +342,7 @@ bool ResourceParser::FlattenXmlSubtree(
}
}
- // Sanity check to make sure we processed all the nodes.
+ // Validity check to make sure we processed all the nodes.
CHECK(node_stack.size() == 1u);
CHECK(node_stack.back() == &root);
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 469128b1e50b..7dfc983b54ba 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -740,7 +740,7 @@ std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const Config
if (type == ResourceType::kId) {
if (res_value.dataType != android::Res_value::TYPE_REFERENCE &&
res_value.dataType != android::Res_value::TYPE_DYNAMIC_REFERENCE) {
- // plain "id" resources are actually encoded as dummy values (aapt1 uses an empty string,
+ // plain "id" resources are actually encoded as unused values (aapt1 uses an empty string,
// while aapt2 uses a false boolean).
return util::make_unique<Id>();
}
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index ab9ce66b0ae3..b1e1a77e1224 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -168,6 +168,7 @@ message OverlayableItem {
ODM = 6;
OEM = 7;
ACTOR = 8;
+ CONFIG_SIGNATURE = 9;
}
// The location of the <item> declaration in source.
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index fb7f6d717c72..f9c54f645e2c 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1401,7 +1401,7 @@ class Linker {
return MergeExportedSymbols(compiled_file.source, compiled_file.exported_symbols);
}
- // Takes a path to load as a ZIP file and merges the files within into the master ResourceTable.
+ // Takes a path to load as a ZIP file and merges the files within into the main ResourceTable.
// If override is true, conflicting resources are allowed to override each other, in order of last
// seen.
// An io::IFileCollection is created from the ZIP file and added to the set of
@@ -1432,7 +1432,7 @@ class Linker {
return !error;
}
- // Takes a path to load and merge into the master ResourceTable. If override is true,
+ // Takes a path to load and merge into the main ResourceTable. If override is true,
// conflicting resources are allowed to override each other, in order of last seen.
// If the file path ends with .flata, .jar, .jack, or .zip the file is treated
// as ZIP archive and the files within are merged individually.
@@ -1449,7 +1449,7 @@ class Linker {
return MergeFile(file, override);
}
- // Takes an AAPT Container file (.apc/.flat) to load and merge into the master ResourceTable.
+ // Takes an AAPT Container file (.apc/.flat) to load and merge into the main ResourceTable.
// If override is true, conflicting resources are allowed to override each other, in order of last
// seen.
// All other file types are ignored. This is because these files could be coming from a zip,
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index e36668e5a043..5b18a3789d76 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -132,8 +132,8 @@ class Optimizer {
if (context_->IsVerbose()) {
context_->GetDiagnostics()->Note(DiagMessage() << "Optimizing APK...");
}
- if (!options_.resources_blacklist.empty()) {
- ResourceFilter filter(options_.resources_blacklist);
+ if (!options_.resources_exclude_list.empty()) {
+ ResourceFilter filter(options_.resources_exclude_list);
if (!filter.Consume(context_, apk->GetResourceTable())) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed filtering resources");
return 1;
@@ -328,7 +328,7 @@ bool ParseConfig(const std::string& content, IAaptContext* context, OptimizeOpti
}
for (StringPiece directive : util::Tokenize(directives, ',')) {
if (directive == "remove") {
- options->resources_blacklist.insert(resource_name.ToResourceName());
+ options->resources_exclude_list.insert(resource_name.ToResourceName());
} else if (directive == "no_collapse" || directive == "no_obfuscate") {
options->table_flattener_options.name_collapse_exemptions.insert(
resource_name.ToResourceName());
diff --git a/tools/aapt2/cmd/Optimize.h b/tools/aapt2/cmd/Optimize.h
index 5070ccc8afbf..3afc46b04af6 100644
--- a/tools/aapt2/cmd/Optimize.h
+++ b/tools/aapt2/cmd/Optimize.h
@@ -36,8 +36,8 @@ struct OptimizeOptions {
// Details of the app extracted from the AndroidManifest.xml
AppInfo app_info;
- // Blacklist of unused resources that should be removed from the apk.
- std::unordered_set<ResourceName> resources_blacklist;
+ // Exclude list of unused resources that should be removed from the apk.
+ std::unordered_set<ResourceName> resources_exclude_list;
// Split APK options.
TableSplitterOptions table_splitter_options;
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index bc2e6990433c..4db2392b4eab 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -35,7 +35,7 @@ constexpr uint32_t u32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
((uint32_t)d);
}
-// Whitelist of PNG chunk types that we want to keep in the resulting PNG.
+// Allow list of PNG chunk types that we want to keep in the resulting PNG.
enum PngChunkTypes {
kPngChunkIHDR = u32(73, 72, 68, 82),
kPngChunkIDAT = u32(73, 68, 65, 84),
@@ -56,7 +56,7 @@ static uint32_t Peek32LE(const char* data) {
return word;
}
-static bool IsPngChunkWhitelisted(uint32_t type) {
+static bool IsPngChunkAllowed(uint32_t type) {
switch (type) {
case kPngChunkIHDR:
case kPngChunkIDAT:
@@ -128,7 +128,7 @@ bool PngChunkFilter::Next(const void** buffer, size_t* len) {
// Do we strip this chunk?
const uint32_t chunk_type = Peek32LE(data_.data() + window_end_ + sizeof(uint32_t));
- if (IsPngChunkWhitelisted(chunk_type)) {
+ if (IsPngChunkAllowed(chunk_type)) {
// Advance the window to include this chunk.
window_end_ += kMinChunkHeaderSize + chunk_len;
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 2ef8b999a192..e5b3107877cb 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -187,7 +187,7 @@ TEST_F(ConfigurationParserTest, ForPath_NoFile) {
TEST_F(ConfigurationParserTest, ExtractConfiguration) {
Maybe<PostProcessingConfiguration> maybe_config =
- ExtractConfiguration(kValidConfig, "dummy.xml", &diag_);
+ ExtractConfiguration(kValidConfig, "fake.xml", &diag_);
PostProcessingConfiguration config = maybe_config.value();
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 53d9ffe21949..71c70da96109 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -188,7 +188,7 @@ class ManifestExtractor {
/** Retrieves the resource assigned to the specified resource id if one exists. */
Value* FindValueById(const ResourceTable* table, const ResourceId& res_id,
- const ConfigDescription& config = DummyConfig()) {
+ const ConfigDescription& config = DefaultConfig()) {
if (table) {
for (auto& package : table->packages) {
if (package->id && package->id.value() == res_id.package_id()) {
@@ -210,7 +210,7 @@ class ManifestExtractor {
}
/** Attempts to resolve the reference to a non-reference value. */
- Value* ResolveReference(Reference* ref, const ConfigDescription& config = DummyConfig()) {
+ Value* ResolveReference(Reference* ref, const ConfigDescription& config = DefaultConfig()) {
const int kMaxIterations = 40;
int i = 0;
while (ref && ref->id && i++ < kMaxIterations) {
@@ -231,10 +231,10 @@ class ManifestExtractor {
* this will attempt to resolve the reference to an integer value.
**/
int32_t* GetAttributeInteger(xml::Attribute* attr,
- const ConfigDescription& config = DummyConfig()) {
+ const ConfigDescription& config = DefaultConfig()) {
if (attr != nullptr) {
if (attr->compiled_value) {
- // Resolve references using the dummy configuration
+ // Resolve references using the configuration
Value* value = attr->compiled_value.get();
if (ValueCast<Reference>(value)) {
value = ResolveReference(ValueCast<Reference>(value), config);
@@ -257,7 +257,7 @@ class ManifestExtractor {
* exist or cannot be resolved to an integer value.
**/
int32_t GetAttributeIntegerDefault(xml::Attribute* attr, int32_t def,
- const ConfigDescription& config = DummyConfig()) {
+ const ConfigDescription& config = DefaultConfig()) {
auto value = GetAttributeInteger(attr, config);
if (value) {
return *value;
@@ -270,10 +270,10 @@ class ManifestExtractor {
* this will attempt to resolve the reference to a string value.
**/
const std::string* GetAttributeString(xml::Attribute* attr,
- const ConfigDescription& config = DummyConfig()) {
+ const ConfigDescription& config = DefaultConfig()) {
if (attr != nullptr) {
if (attr->compiled_value) {
- // Resolve references using the dummy configuration
+ // Resolve references using the configuration
Value* value = attr->compiled_value.get();
if (ValueCast<Reference>(value)) {
value = ResolveReference(ValueCast<Reference>(value), config);
@@ -305,7 +305,7 @@ class ManifestExtractor {
* exist or cannot be resolved to an string value.
**/
std::string GetAttributeStringDefault(xml::Attribute* attr, std::string def,
- const ConfigDescription& config = DummyConfig()) {
+ const ConfigDescription& config = DefaultConfig()) {
auto value = GetAttributeString(attr, config);
if (value) {
return *value;
@@ -322,7 +322,7 @@ class ManifestExtractor {
friend Element;
/** Creates a default configuration used to retrieve resources. */
- static ConfigDescription DummyConfig() {
+ static ConfigDescription DefaultConfig() {
ConfigDescription config;
config.orientation = android::ResTable_config::ORIENTATION_PORT;
config.density = android::ResTable_config::DENSITY_MEDIUM;
@@ -1871,7 +1871,7 @@ bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) {
// Collect all the unique locales of the apk
if (locales_.find(locale_str) == locales_.end()) {
- ConfigDescription config = ManifestExtractor::DummyConfig();
+ ConfigDescription config = ManifestExtractor::DefaultConfig();
config.setBcp47Locale(locale_str.data());
locales_.insert(std::make_pair(locale_str, config));
}
@@ -1880,7 +1880,7 @@ bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) {
uint16_t density = (value->config.density == 0) ? (uint16_t) 160
: value->config.density;
if (densities_.find(density) == densities_.end()) {
- ConfigDescription config = ManifestExtractor::DummyConfig();
+ ConfigDescription config = ManifestExtractor::DefaultConfig();
config.density = density;
densities_.insert(std::make_pair(density, config));
}
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index 59627ce579af..6932baf76c75 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -776,6 +776,7 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) {
OverlayableItem overlayable_item_three(group_one);
overlayable_item_three.policies |= PolicyFlags::SIGNATURE;
overlayable_item_three.policies |= PolicyFlags::ACTOR_SIGNATURE;
+ overlayable_item_three.policies |= PolicyFlags::CONFIG_SIGNATURE;
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
@@ -830,7 +831,8 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) {
EXPECT_EQ(result_overlayable.overlayable->name, "OtherName");
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization");
EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE
- | PolicyFlags::ACTOR_SIGNATURE);
+ | PolicyFlags::ACTOR_SIGNATURE
+ | PolicyFlags::CONFIG_SIGNATURE);
}
TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 582bd3983265..06ac9e5dc5c4 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -404,6 +404,9 @@ bool DeserializeOverlayableItemFromPb(const pb::OverlayableItem& pb_overlayable,
case pb::OverlayableItem::ACTOR:
out_overlayable->policies |= PolicyFlags::ACTOR_SIGNATURE;
break;
+ case pb::OverlayableItem::CONFIG_SIGNATURE:
+ out_overlayable->policies |= PolicyFlags::CONFIG_SIGNATURE;
+ break;
default:
*out_error = "unknown overlayable policy";
return false;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 5ab43b7be378..98c517510028 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -325,6 +325,9 @@ static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item
if (overlayable_item.policies & PolicyFlags::ACTOR_SIGNATURE) {
pb_overlayable_item->add_policy(pb::OverlayableItem::ACTOR);
}
+ if (overlayable_item.policies & PolicyFlags::CONFIG_SIGNATURE) {
+ pb_overlayable_item->add_policy(pb::OverlayableItem::CONFIG_SIGNATURE);
+ }
if (source_pool != nullptr) {
SerializeSourceToPb(overlayable_item.source, source_pool,
diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp
index ba9646f9aeb4..ec3c5431c7a3 100644
--- a/tools/aapt2/jni/aapt2_jni.cpp
+++ b/tools/aapt2/jni/aapt2_jni.cpp
@@ -139,5 +139,5 @@ JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(JNIEnv*
JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping(
JNIEnv *env, jclass aapt_obj) {
- // This is just a dummy method to see if the library has been loaded.
+ // This is just a no-op method to see if the library has been loaded.
}
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 49f8e1bcd30b..dac21d7e9200 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -570,8 +570,8 @@ bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
}
xml::XmlActionExecutorPolicy policy = options_.warn_validation
- ? xml::XmlActionExecutorPolicy::kWhitelistWarning
- : xml::XmlActionExecutorPolicy::kWhitelist;
+ ? xml::XmlActionExecutorPolicy::kAllowListWarning
+ : xml::XmlActionExecutorPolicy::kAllowList;
if (!executor.Execute(policy, context->GetDiagnostics(), doc)) {
return false;
}
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index c25e4503a208..ad56092754aa 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -31,11 +31,11 @@ namespace aapt {
TableMerger::TableMerger(IAaptContext* context, ResourceTable* out_table,
const TableMergerOptions& options)
- : context_(context), master_table_(out_table), options_(options) {
+ : context_(context), main_table_(out_table), options_(options) {
// Create the desired package that all tables will be merged into.
- master_package_ =
- master_table_->CreatePackage(context_->GetCompilationPackage(), context_->GetPackageId());
- CHECK(master_package_ != nullptr) << "package name or ID already taken";
+ main_package_ =
+ main_table_->CreatePackage(context_->GetCompilationPackage(), context_->GetPackageId());
+ CHECK(main_package_ != nullptr) << "package name or ID already taken";
}
bool TableMerger::Merge(const Source& src, ResourceTable* table, bool overlay) {
@@ -235,7 +235,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTablePackage* src_package,
bool error = false;
for (auto& src_type : src_package->types) {
- ResourceTableType* dst_type = master_package_->FindOrCreateType(src_type->type);
+ ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->type);
if (!MergeType(context_, src, dst_type, src_type.get())) {
error = true;
continue;
@@ -279,7 +279,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTablePackage* src_package,
if (dst_config_value) {
CollisionResult collision_result = MergeConfigValue(
context_, res_name, overlay, options_.override_styles_instead_of_overlaying,
- dst_config_value, src_config_value.get(), &master_table_->string_pool);
+ dst_config_value, src_config_value.get(), &main_table_->string_pool);
if (collision_result == CollisionResult::kConflict) {
error = true;
continue;
@@ -298,7 +298,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTablePackage* src_package,
if (mangle_package) {
new_file_ref = CloneAndMangleFile(src_package->name, *f);
} else {
- new_file_ref = std::unique_ptr<FileReference>(f->Clone(&master_table_->string_pool));
+ new_file_ref = std::unique_ptr<FileReference>(f->Clone(&main_table_->string_pool));
}
dst_config_value->value = std::move(new_file_ref);
@@ -307,7 +307,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTablePackage* src_package,
? dst_config_value->value->GetComment() : Maybe<std::string>();
dst_config_value->value = std::unique_ptr<Value>(
- src_config_value->value->Clone(&master_table_->string_pool));
+ src_config_value->value->Clone(&main_table_->string_pool));
// Keep the comment from the original resource and ignore all comments from overlaying
// resources
@@ -328,14 +328,14 @@ std::unique_ptr<FileReference> TableMerger::CloneAndMangleFile(
std::string mangled_entry = NameMangler::MangleEntry(package, entry.to_string());
std::string newPath = prefix.to_string() + mangled_entry + suffix.to_string();
std::unique_ptr<FileReference> new_file_ref =
- util::make_unique<FileReference>(master_table_->string_pool.MakeRef(newPath));
+ util::make_unique<FileReference>(main_table_->string_pool.MakeRef(newPath));
new_file_ref->SetComment(file_ref.GetComment());
new_file_ref->SetSource(file_ref.GetSource());
new_file_ref->type = file_ref.type;
new_file_ref->file = file_ref.file;
return new_file_ref;
}
- return std::unique_ptr<FileReference>(file_ref.Clone(&master_table_->string_pool));
+ return std::unique_ptr<FileReference>(file_ref.Clone(&main_table_->string_pool));
}
bool TableMerger::MergeFile(const ResourceFile& file_desc, bool overlay, io::IFile* file) {
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index a35a134a887d..e01a0c186392 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -80,9 +80,9 @@ class TableMerger {
DISALLOW_COPY_AND_ASSIGN(TableMerger);
IAaptContext* context_;
- ResourceTable* master_table_;
+ ResourceTable* main_table_;
TableMergerOptions options_;
- ResourceTablePackage* master_package_;
+ ResourceTablePackage* main_package_;
std::set<std::string> merged_packages_;
bool MergeImpl(const Source& src, ResourceTable* src_table, bool overlay, bool allow_new);
diff --git a/tools/aapt2/link/XmlCompatVersioner.cpp b/tools/aapt2/link/XmlCompatVersioner.cpp
index 20ebdc696814..6937ca961f06 100644
--- a/tools/aapt2/link/XmlCompatVersioner.cpp
+++ b/tools/aapt2/link/XmlCompatVersioner.cpp
@@ -143,8 +143,8 @@ std::vector<std::unique_ptr<xml::XmlResource>> XmlCompatVersioner::Process(
// Iterate from smallest to largest API version.
for (ApiVersion api : apis_referenced) {
- std::set<ApiVersion> dummy;
- versioned_docs.push_back(ProcessDoc(api, api_range.end, doc, &dummy));
+ std::set<ApiVersion> tmp;
+ versioned_docs.push_back(ProcessDoc(api, api_range.end, doc, &tmp));
}
return versioned_docs;
}
diff --git a/tools/aapt2/optimize/ResourceFilter.cpp b/tools/aapt2/optimize/ResourceFilter.cpp
index 250b65197a7d..08c045bf68f7 100644
--- a/tools/aapt2/optimize/ResourceFilter.cpp
+++ b/tools/aapt2/optimize/ResourceFilter.cpp
@@ -20,8 +20,8 @@
namespace aapt {
-ResourceFilter::ResourceFilter(const std::unordered_set<ResourceName>& blacklist)
- : blacklist_(blacklist) {
+ResourceFilter::ResourceFilter(const std::unordered_set<ResourceName>& exclude_list)
+ : exclude_list_(exclude_list) {
}
bool ResourceFilter::Consume(IAaptContext* context, ResourceTable* table) {
@@ -29,7 +29,7 @@ bool ResourceFilter::Consume(IAaptContext* context, ResourceTable* table) {
for (auto& type : package->types) {
for (auto it = type->entries.begin(); it != type->entries.end(); ) {
ResourceName resource = ResourceName({}, type->type, (*it)->name);
- if (blacklist_.find(resource) != blacklist_.end()) {
+ if (exclude_list_.find(resource) != exclude_list_.end()) {
it = type->entries.erase(it);
} else {
++it;
diff --git a/tools/aapt2/optimize/ResourceFilter.h b/tools/aapt2/optimize/ResourceFilter.h
index d4baf654b0ff..a2645333e497 100644
--- a/tools/aapt2/optimize/ResourceFilter.h
+++ b/tools/aapt2/optimize/ResourceFilter.h
@@ -25,16 +25,16 @@
namespace aapt {
-// Removes non-whitelisted entries from resource table.
+// Removes exclude-listed entries from resource table.
class ResourceFilter : public IResourceTableConsumer {
public:
- explicit ResourceFilter(const std::unordered_set<ResourceName>& blacklist);
+ explicit ResourceFilter(const std::unordered_set<ResourceName>& exclude_list);
bool Consume(IAaptContext* context, ResourceTable* table) override;
private:
DISALLOW_COPY_AND_ASSIGN(ResourceFilter);
- std::unordered_set<ResourceName> blacklist_;
+ std::unordered_set<ResourceName> exclude_list_;
};
} // namespace aapt
diff --git a/tools/aapt2/optimize/ResourceFilter_test.cpp b/tools/aapt2/optimize/ResourceFilter_test.cpp
index ef57f9c56dab..34d8fd280fa9 100644
--- a/tools/aapt2/optimize/ResourceFilter_test.cpp
+++ b/tools/aapt2/optimize/ResourceFilter_test.cpp
@@ -31,22 +31,22 @@ TEST(ResourceFilterTest, SomeValuesAreFilteredOut) {
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
- .AddString("android:string/notblacklisted", ResourceId{}, default_config, "value")
- .AddString("android:string/blacklisted", ResourceId{}, default_config, "value")
- .AddString("android:string/notblacklisted2", ResourceId{}, default_config, "value")
- .AddString("android:string/blacklisted2", ResourceId{}, default_config, "value")
+ .AddString("android:string/notexclude_listed", ResourceId{}, default_config, "value")
+ .AddString("android:string/exclude_listed", ResourceId{}, default_config, "value")
+ .AddString("android:string/notexclude_listed2", ResourceId{}, default_config, "value")
+ .AddString("android:string/exclude_listed2", ResourceId{}, default_config, "value")
.Build();
- std::unordered_set<ResourceName> blacklist = {
- ResourceName({}, ResourceType::kString, "blacklisted"),
- ResourceName({}, ResourceType::kString, "blacklisted2"),
+ std::unordered_set<ResourceName> exclude_list = {
+ ResourceName({}, ResourceType::kString, "exclude_listed"),
+ ResourceName({}, ResourceType::kString, "exclude_listed2"),
};
- ASSERT_TRUE(ResourceFilter(blacklist).Consume(context.get(), table.get()));
- EXPECT_THAT(table, HasValue("android:string/notblacklisted", default_config));
- EXPECT_THAT(table, HasValue("android:string/notblacklisted2", default_config));
- EXPECT_THAT(table, Not(HasValue("android:string/blacklisted", default_config)));
- EXPECT_THAT(table, Not(HasValue("android:string/blacklisted2", default_config)));
+ ASSERT_TRUE(ResourceFilter(exclude_list).Consume(context.get(), table.get()));
+ EXPECT_THAT(table, HasValue("android:string/notexclude_listed", default_config));
+ EXPECT_THAT(table, HasValue("android:string/notexclude_listed2", default_config));
+ EXPECT_THAT(table, Not(HasValue("android:string/exclude_listed", default_config)));
+ EXPECT_THAT(table, Not(HasValue("android:string/exclude_listed2", default_config)));
}
TEST(ResourceFilterTest, TypeIsCheckedBeforeFiltering) {
@@ -55,21 +55,21 @@ TEST(ResourceFilterTest, TypeIsCheckedBeforeFiltering) {
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
- .AddString("android:string/notblacklisted", ResourceId{}, default_config, "value")
- .AddString("android:string/blacklisted", ResourceId{}, default_config, "value")
- .AddString("android:drawable/notblacklisted", ResourceId{}, default_config, "value")
- .AddString("android:drawable/blacklisted", ResourceId{}, default_config, "value")
+ .AddString("android:string/notexclude_listed", ResourceId{}, default_config, "value")
+ .AddString("android:string/exclude_listed", ResourceId{}, default_config, "value")
+ .AddString("android:drawable/notexclude_listed", ResourceId{}, default_config, "value")
+ .AddString("android:drawable/exclude_listed", ResourceId{}, default_config, "value")
.Build();
- std::unordered_set<ResourceName> blacklist = {
- ResourceName({}, ResourceType::kString, "blacklisted"),
+ std::unordered_set<ResourceName> exclude_list = {
+ ResourceName({}, ResourceType::kString, "exclude_listed"),
};
- ASSERT_TRUE(ResourceFilter(blacklist).Consume(context.get(), table.get()));
- EXPECT_THAT(table, HasValue("android:string/notblacklisted", default_config));
- EXPECT_THAT(table, HasValue("android:drawable/blacklisted", default_config));
- EXPECT_THAT(table, HasValue("android:drawable/notblacklisted", default_config));
- EXPECT_THAT(table, Not(HasValue("android:string/blacklisted", default_config)));
+ ASSERT_TRUE(ResourceFilter(exclude_list).Consume(context.get(), table.get()));
+ EXPECT_THAT(table, HasValue("android:string/notexclude_listed", default_config));
+ EXPECT_THAT(table, HasValue("android:drawable/exclude_listed", default_config));
+ EXPECT_THAT(table, HasValue("android:drawable/notexclude_listed", default_config));
+ EXPECT_THAT(table, Not(HasValue("android:string/exclude_listed", default_config)));
}
} // namespace aapt
diff --git a/tools/aapt2/test/Common.cpp b/tools/aapt2/test/Common.cpp
index b54c155ddc2f..23c22185a53f 100644
--- a/tools/aapt2/test/Common.cpp
+++ b/tools/aapt2/test/Common.cpp
@@ -21,7 +21,7 @@ using android::ConfigDescription;
namespace aapt {
namespace test {
-struct DummyDiagnosticsImpl : public IDiagnostics {
+struct TestDiagnosticsImpl : public IDiagnostics {
void Log(Level level, DiagMessageActual& actual_msg) override {
switch (level) {
case Level::Note:
@@ -39,7 +39,7 @@ struct DummyDiagnosticsImpl : public IDiagnostics {
};
IDiagnostics* GetDiagnostics() {
- static DummyDiagnosticsImpl diag;
+ static TestDiagnosticsImpl diag;
return &diag;
}
diff --git a/tools/aapt2/trace/TraceBuffer.h b/tools/aapt2/trace/TraceBuffer.h
index 8618e0eeb731..ba751dd72f41 100644
--- a/tools/aapt2/trace/TraceBuffer.h
+++ b/tools/aapt2/trace/TraceBuffer.h
@@ -40,7 +40,7 @@ public:
void BeginTrace(const std::string& tag);
void EndTrace();
-// A master trace is required to flush events to disk. Events are formatted in systrace
+// A main trace is required to flush events to disk. Events are formatted in systrace
// json format.
class FlushTrace {
public:
diff --git a/tools/aapt2/util/Maybe_test.cpp b/tools/aapt2/util/Maybe_test.cpp
index 2057ddcc9e45..4c921f13a3ca 100644
--- a/tools/aapt2/util/Maybe_test.cpp
+++ b/tools/aapt2/util/Maybe_test.cpp
@@ -22,32 +22,32 @@
namespace aapt {
-struct Dummy {
- Dummy() {
+struct Fake {
+ Fake() {
data = new int;
*data = 1;
- std::cerr << "Construct Dummy{0x" << (void*)this << "} with data=0x"
+ std::cerr << "Construct Fake{0x" << (void*)this << "} with data=0x"
<< (void*)data << std::endl;
}
- Dummy(const Dummy& rhs) {
+ Fake(const Fake& rhs) {
data = nullptr;
if (rhs.data) {
data = new int;
*data = *rhs.data;
}
- std::cerr << "CopyConstruct Dummy{0x" << (void*)this << "} from Dummy{0x"
+ std::cerr << "CopyConstruct Fake{0x" << (void*)this << "} from Fake{0x"
<< (const void*)&rhs << "}" << std::endl;
}
- Dummy(Dummy&& rhs) {
+ Fake(Fake&& rhs) {
data = rhs.data;
rhs.data = nullptr;
- std::cerr << "MoveConstruct Dummy{0x" << (void*)this << "} from Dummy{0x"
+ std::cerr << "MoveConstruct Fake{0x" << (void*)this << "} from Fake{0x"
<< (const void*)&rhs << "}" << std::endl;
}
- Dummy& operator=(const Dummy& rhs) {
+ Fake& operator=(const Fake& rhs) {
delete data;
data = nullptr;
@@ -55,22 +55,22 @@ struct Dummy {
data = new int;
*data = *rhs.data;
}
- std::cerr << "CopyAssign Dummy{0x" << (void*)this << "} from Dummy{0x"
+ std::cerr << "CopyAssign Fake{0x" << (void*)this << "} from Fake{0x"
<< (const void*)&rhs << "}" << std::endl;
return *this;
}
- Dummy& operator=(Dummy&& rhs) {
+ Fake& operator=(Fake&& rhs) {
delete data;
data = rhs.data;
rhs.data = nullptr;
- std::cerr << "MoveAssign Dummy{0x" << (void*)this << "} from Dummy{0x"
+ std::cerr << "MoveAssign Fake{0x" << (void*)this << "} from Fake{0x"
<< (const void*)&rhs << "}" << std::endl;
return *this;
}
- ~Dummy() {
- std::cerr << "Destruct Dummy{0x" << (void*)this << "} with data=0x"
+ ~Fake() {
+ std::cerr << "Destruct Fake{0x" << (void*)this << "} with data=0x"
<< (void*)data << std::endl;
delete data;
}
@@ -100,15 +100,15 @@ TEST(MaybeTest, MakeSomething) {
}
TEST(MaybeTest, Lifecycle) {
- Maybe<Dummy> val = make_nothing<Dummy>();
+ Maybe<Fake> val = make_nothing<Fake>();
- Maybe<Dummy> val2 = make_value(Dummy());
+ Maybe<Fake> val2 = make_value(Fake());
}
TEST(MaybeTest, MoveAssign) {
- Maybe<Dummy> val;
+ Maybe<Fake> val;
{
- Maybe<Dummy> val2 = Dummy();
+ Maybe<Fake> val2 = Fake();
val = std::move(val2);
}
}
diff --git a/tools/aapt2/xml/XmlActionExecutor.cpp b/tools/aapt2/xml/XmlActionExecutor.cpp
index cb844f085ecc..fab17c949dd8 100644
--- a/tools/aapt2/xml/XmlActionExecutor.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor.cpp
@@ -74,11 +74,11 @@ bool XmlNodeAction::Execute(XmlActionExecutorPolicy policy, std::vector<StringPi
for (const StringPiece& element : *bread_crumb) {
error_msg << "<" << element << ">";
}
- if (policy == XmlActionExecutorPolicy::kWhitelistWarning) {
+ if (policy == XmlActionExecutorPolicy::kAllowListWarning) {
// Treat the error only as a warning.
diag->Warn(error_msg);
} else {
- // Policy is XmlActionExecutorPolicy::kWhitelist, we should fail.
+ // Policy is XmlActionExecutorPolicy::kAllowList, we should fail.
diag->Error(error_msg);
error = true;
}
@@ -94,7 +94,7 @@ bool XmlActionExecutor::Execute(XmlActionExecutorPolicy policy, IDiagnostics* di
Element* el = doc->root.get();
if (!el) {
- if (policy == XmlActionExecutorPolicy::kWhitelist) {
+ if (policy == XmlActionExecutorPolicy::kAllowList) {
source_diag.Error(DiagMessage() << "no root XML tag found");
return false;
}
@@ -109,7 +109,7 @@ bool XmlActionExecutor::Execute(XmlActionExecutorPolicy policy, IDiagnostics* di
return iter->second.Execute(policy, &bread_crumb, &source_diag, el);
}
- if (policy == XmlActionExecutorPolicy::kWhitelist) {
+ if (policy == XmlActionExecutorPolicy::kAllowList) {
DiagMessage error_msg(el->line_number);
error_msg << "unexpected root element ";
PrintElementToDiagMessage(el, &error_msg);
diff --git a/tools/aapt2/xml/XmlActionExecutor.h b/tools/aapt2/xml/XmlActionExecutor.h
index f689b2a3eaa8..a0ad1dadeddf 100644
--- a/tools/aapt2/xml/XmlActionExecutor.h
+++ b/tools/aapt2/xml/XmlActionExecutor.h
@@ -37,12 +37,12 @@ enum class XmlActionExecutorPolicy {
// The actions defined must match and run. If an element is found that does not match an action,
// an error occurs.
// Note: namespaced elements are always ignored.
- kWhitelist,
+ kAllowList,
// The actions defined should match and run. if an element is found that does not match an
// action, a warning is printed.
// Note: namespaced elements are always ignored.
- kWhitelistWarning,
+ kAllowListWarning,
};
// Contains the actions to perform at this XML node. This is a recursive data structure that
diff --git a/tools/aapt2/xml/XmlActionExecutor_test.cpp b/tools/aapt2/xml/XmlActionExecutor_test.cpp
index d39854e5fe4e..d47b49590f5c 100644
--- a/tools/aapt2/xml/XmlActionExecutor_test.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor_test.cpp
@@ -60,10 +60,10 @@ TEST(XmlActionExecutorTest, FailsWhenUndefinedHierarchyExists) {
StdErrDiagnostics diag;
doc = test::BuildXmlDom("<manifest><application /><activity /></manifest>");
- ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kWhitelist, &diag, doc.get()));
+ ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kAllowList, &diag, doc.get()));
doc = test::BuildXmlDom("<manifest><application><activity /></application></manifest>");
- ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kWhitelist, &diag, doc.get()));
+ ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kAllowList, &diag, doc.get()));
}
} // namespace xml
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index f25fcdcb7479..99aaa3c4d6e5 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -11,7 +11,7 @@ else
if (( count == 0 )); then
echo
fi
- echo -e "\033[0;31mThe source of truth for '$file' is in AOSP.\033[0m"
+ echo -e "\033[0;31;47mThe source of truth for '$file' is in AOSP.\033[0m"
(( count++ ))
done < <(git show --name-only --pretty=format: $1 | grep -- "$2")
if (( count != 0 )); then
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index de6b4785ec37..8a282e5f0821 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -13,9 +13,7 @@
# 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.
-"""
-Generate API lists for non-SDK API enforcement.
-"""
+"""Generate API lists for non-SDK API enforcement."""
import argparse
from collections import defaultdict
import functools
@@ -24,27 +22,47 @@ import re
import sys
# Names of flags recognized by the `hiddenapi` tool.
-FLAG_WHITELIST = "whitelist"
-FLAG_GREYLIST = "greylist"
-FLAG_BLACKLIST = "blacklist"
-FLAG_GREYLIST_MAX_O = "greylist-max-o"
-FLAG_GREYLIST_MAX_P = "greylist-max-p"
-FLAG_GREYLIST_MAX_Q = "greylist-max-q"
-FLAG_GREYLIST_MAX_R = "greylist-max-r"
-FLAG_CORE_PLATFORM_API = "core-platform-api"
-FLAG_PUBLIC_API = "public-api"
-FLAG_SYSTEM_API = "system-api"
-FLAG_TEST_API = "test-api"
+FLAG_SDK = 'sdk'
+FLAG_UNSUPPORTED = 'unsupported'
+FLAG_BLOCKED = 'blocked'
+FLAG_MAX_TARGET_O = 'max-target-o'
+FLAG_MAX_TARGET_P = 'max-target-p'
+FLAG_MAX_TARGET_Q = 'max-target-q'
+FLAG_MAX_TARGET_R = 'max-target-r'
+FLAG_CORE_PLATFORM_API = 'core-platform-api'
+FLAG_PUBLIC_API = 'public-api'
+FLAG_SYSTEM_API = 'system-api'
+FLAG_TEST_API = 'test-api'
+
+OLD_FLAG_SDK = "whitelist"
+OLD_FLAG_UNSUPPORTED = "greylist"
+OLD_FLAG_BLOCKED = "blacklist"
+OLD_FLAG_MAX_TARGET_O = "greylist-max-o"
+OLD_FLAG_MAX_TARGET_P = "greylist-max-p"
+OLD_FLAG_MAX_TARGET_Q = "greylist-max-q"
+OLD_FLAG_MAX_TARGET_R = "greylist-max-r"
+
+OLD_FLAGS_TO_NEW = {
+ OLD_FLAG_SDK: FLAG_SDK,
+ OLD_FLAG_UNSUPPORTED: FLAG_UNSUPPORTED,
+ OLD_FLAG_BLOCKED: FLAG_BLOCKED,
+ OLD_FLAG_MAX_TARGET_O: FLAG_MAX_TARGET_O,
+ OLD_FLAG_MAX_TARGET_P: FLAG_MAX_TARGET_P,
+ OLD_FLAG_MAX_TARGET_Q: FLAG_MAX_TARGET_Q,
+ OLD_FLAG_MAX_TARGET_R: FLAG_MAX_TARGET_R,
+}
+
+NEW_FLAGS_TO_OLD = dict(zip(OLD_FLAGS_TO_NEW.values(), OLD_FLAGS_TO_NEW.keys()))
# List of all known flags.
FLAGS_API_LIST = [
- FLAG_WHITELIST,
- FLAG_GREYLIST,
- FLAG_BLACKLIST,
- FLAG_GREYLIST_MAX_O,
- FLAG_GREYLIST_MAX_P,
- FLAG_GREYLIST_MAX_Q,
- FLAG_GREYLIST_MAX_R,
+ FLAG_SDK,
+ FLAG_UNSUPPORTED,
+ FLAG_BLOCKED,
+ FLAG_MAX_TARGET_O,
+ FLAG_MAX_TARGET_P,
+ FLAG_MAX_TARGET_Q,
+ FLAG_MAX_TARGET_R,
]
ALL_FLAGS = FLAGS_API_LIST + [
FLAG_CORE_PLATFORM_API,
@@ -58,7 +76,7 @@ ALL_FLAGS_SET = set(ALL_FLAGS)
# Suffix used in command line args to express that only known and
# otherwise unassigned entries should be assign the given flag.
-# For example, the P dark greylist is checked in as it was in P,
+# For example, the max-target-P list is checked in as it was in P,
# but signatures have changes since then. The flag instructs this
# script to skip any entries which do not exist any more.
FLAG_IGNORE_CONFLICTS_SUFFIX = "-ignore-conflicts"
@@ -87,6 +105,7 @@ SERIALIZATION_REGEX = re.compile(r'.*->(' + '|'.join(SERIALIZATION_PATTERNS) + r
HAS_NO_API_LIST_ASSIGNED = lambda api, flags: not FLAGS_API_LIST_SET.intersection(flags)
IS_SERIALIZATION = lambda api, flags: SERIALIZATION_REGEX.match(api)
+
def get_args():
"""Parses command line arguments.
@@ -113,6 +132,7 @@ def get_args():
return parser.parse_args()
+
def read_lines(filename):
"""Reads entire file and return it as a list of lines.
@@ -130,8 +150,9 @@ def read_lines(filename):
lines = map(lambda line: line.strip(), lines)
return set(lines)
+
def write_lines(filename, lines):
- """Writes list of lines into a file, overwriting the file it it exists.
+ """Writes list of lines into a file, overwriting the file if it exists.
Args:
filename (string): Path to the file to be writting into.
@@ -141,6 +162,7 @@ def write_lines(filename, lines):
with open(filename, 'w') as f:
f.writelines(lines)
+
def extract_package(signature):
"""Extracts the package from a signature.
@@ -159,6 +181,7 @@ def extract_package(signature):
package_name = full_class_name.rpartition("/")[0]
return package_name.replace('/', '.')
+
class FlagsDict:
def __init__(self):
self._dict_keyset = set()
@@ -182,6 +205,36 @@ class FlagsDict:
"Please visit go/hiddenapi for more information.").format(
source, "\n".join(flags_subset - ALL_FLAGS_SET))
+ def convert_to_new_flag(self, flag):
+ """Converts old flag to a new variant.
+
+ Flags that are considered old are replaced with new versions.
+ Otherwise, it is a no-op.
+
+ Args:
+ flag: a string, representing SDK flag.
+
+ Returns:
+ A string. Result of conversion.
+
+ """
+ return OLD_FLAGS_TO_NEW.get(flag, flag)
+
+ def convert_to_old_flag(self, flag):
+ """Converts a new flag to a old variant.
+
+ No-op if there is no suitable old flag.
+ Only used to support backwards compatibility.
+
+ Args:
+ flag: a string, representing SDK flag.
+
+ Returns:
+ A string. Result of conversion.
+
+ """
+ return NEW_FLAGS_TO_OLD.get(flag, flag)
+
def filter_apis(self, filter_fn):
"""Returns APIs which match a given predicate.
@@ -212,10 +265,16 @@ class FlagsDict:
def generate_csv(self):
"""Constructs CSV entries from a dictionary.
+ Old versions of flags are used to generate the file.
+
Returns:
List of lines comprising a CSV file. See "parse_and_merge_csv" for format description.
"""
- return sorted(map(lambda api: ",".join([api] + sorted(self._dict[api])), self._dict))
+ lines = []
+ for api in self._dict:
+ flags = sorted([self.convert_to_old_flag(flag) for flag in self._dict[api]])
+ lines.append(",".join([api] + flags))
+ return sorted(lines)
def parse_and_merge_csv(self, csv_lines, source = "<unknown>"):
"""Parses CSV entries and merges them into a given dictionary.
@@ -237,17 +296,16 @@ class FlagsDict:
self._dict_keyset.update([ csv[0] for csv in csv_values ])
# Check that all flags are known.
- csv_flags = set(functools.reduce(
- lambda x, y: set(x).union(y),
- [ csv[1:] for csv in csv_values ],
- []))
+ csv_flags = set()
+ for csv in csv_values:
+ csv_flags.update([self.convert_to_new_flag(flag) for flag in csv[1:]])
self._check_flags_set(csv_flags, source)
# Iterate over all CSV lines, find entry in dict and append flags to it.
for csv in csv_values:
- flags = csv[1:]
+ flags = [self.convert_to_new_flag(flag) for flag in csv[1:]]
if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
- flags.append(FLAG_WHITELIST)
+ flags.append(FLAG_SDK)
self._dict[csv[0]].update(flags)
def assign_flag(self, flag, apis, source="<unknown>"):
@@ -271,6 +329,7 @@ class FlagsDict:
for api in apis:
self._dict[api].add(flag)
+
def main(argv):
# Parse arguments.
args = vars(get_args())
@@ -287,8 +346,8 @@ def main(argv):
flags.parse_and_merge_csv(read_lines(filename), filename)
# Combine inputs which do not require any particular order.
- # (1) Assign serialization API to whitelist.
- flags.assign_flag(FLAG_WHITELIST, flags.filter_apis(IS_SERIALIZATION))
+ # (1) Assign serialization API to SDK.
+ flags.assign_flag(FLAG_SDK, flags.filter_apis(IS_SERIALIZATION))
# (2) Merge text files with a known flag into the dictionary.
for flag in ALL_FLAGS:
@@ -314,8 +373,8 @@ def main(argv):
valid_entries = flags.filter_apis(should_add_signature_to_list)
flags.assign_flag(flag, valid_entries)
- # Assign all remaining entries to the blacklist.
- flags.assign_flag(FLAG_BLACKLIST, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
+ # Mark all remaining entries as blocked.
+ flags.assign_flag(FLAG_BLOCKED, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
# Write output.
write_lines(args["output"], flags.generate_csv())
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
index 55c3a7d718db..321c400ef898 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py
@@ -23,7 +23,7 @@ class TestHiddenapiListGeneration(unittest.TestCase):
# Initialize flags so that A and B are put on the whitelist and
# C, D, E are left unassigned. Try filtering for the unassigned ones.
flags = FlagsDict()
- flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B,' + FLAG_WHITELIST,
+ flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B,' + FLAG_SDK,
'C', 'D', 'E'])
filter_set = flags.filter_apis(lambda api, flags: not flags)
self.assertTrue(isinstance(filter_set, set))
@@ -32,10 +32,10 @@ class TestHiddenapiListGeneration(unittest.TestCase):
def test_get_valid_subset_of_unassigned_keys(self):
# Create flags where only A is unassigned.
flags = FlagsDict()
- flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B', 'C'])
- flags.assign_flag(FLAG_GREYLIST, set(['C']))
+ flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B', 'C'])
+ flags.assign_flag(FLAG_UNSUPPORTED, set(['C']))
self.assertEqual(flags.generate_csv(),
- [ 'A,' + FLAG_WHITELIST, 'B', 'C,' + FLAG_GREYLIST ])
+ [ 'A,' + OLD_FLAG_SDK, 'B', 'C,' + OLD_FLAG_UNSUPPORTED ])
# Check three things:
# (1) B is selected as valid unassigned
@@ -50,20 +50,21 @@ class TestHiddenapiListGeneration(unittest.TestCase):
# Test empty CSV entry.
self.assertEqual(flags.generate_csv(), [])
- # Test new additions.
+ # Test new additions. CSV generator produces values with old flags
+ # to be backwards compatible.
flags.parse_and_merge_csv([
- 'A,' + FLAG_GREYLIST,
- 'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O,
- 'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
- 'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
- 'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
+ 'A,' + FLAG_UNSUPPORTED,
+ 'B,' + FLAG_BLOCKED + ',' + FLAG_MAX_TARGET_O,
+ 'C,' + FLAG_SDK + ',' + FLAG_SYSTEM_API,
+ 'D,' + FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
+ 'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
])
self.assertEqual(flags.generate_csv(), [
- 'A,' + FLAG_GREYLIST,
- 'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O,
- 'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
- 'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
- 'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
+ 'A,' + OLD_FLAG_UNSUPPORTED,
+ 'B,' + OLD_FLAG_BLOCKED + "," + OLD_FLAG_MAX_TARGET_O,
+ 'C,' + FLAG_SYSTEM_API + ',' + OLD_FLAG_SDK,
+ 'D,' + OLD_FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
+ 'E,' + OLD_FLAG_BLOCKED + ',' + FLAG_TEST_API,
])
# Test unknown flag.
@@ -72,16 +73,16 @@ class TestHiddenapiListGeneration(unittest.TestCase):
def test_assign_flag(self):
flags = FlagsDict()
- flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B'])
+ flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B'])
# Test new additions.
- flags.assign_flag(FLAG_GREYLIST, set([ 'A', 'B' ]))
+ flags.assign_flag(FLAG_UNSUPPORTED, set([ 'A', 'B' ]))
self.assertEqual(flags.generate_csv(),
- [ 'A,' + FLAG_GREYLIST + "," + FLAG_WHITELIST, 'B,' + FLAG_GREYLIST ])
+ [ 'A,' + OLD_FLAG_UNSUPPORTED + "," + OLD_FLAG_SDK, 'B,' + OLD_FLAG_UNSUPPORTED ])
# Test invalid API signature.
with self.assertRaises(AssertionError):
- flags.assign_flag(FLAG_WHITELIST, set([ 'C' ]))
+ flags.assign_flag(FLAG_SDK, set([ 'C' ]))
# Test invalid flag.
with self.assertRaises(AssertionError):
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 4c741c49cfdb..fe6ca558a0ee 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -72,7 +72,7 @@ static void print_error(const FieldDescriptor* field, const char* format, ...) {
SourceLocation loc;
if (field->GetSourceLocation(&loc)) {
- // TODO: this will work if we can figure out how to pass
+ // TODO(b/162454173): this will work if we can figure out how to pass
// --include_source_info to protoc
fprintf(stderr, "%s:%d: ", file->name().c_str(), loc.start_line);
} else {
@@ -111,7 +111,6 @@ static java_type_t java_type(const FieldDescriptor* field) {
case FieldDescriptor::TYPE_GROUP:
return JAVA_TYPE_UNKNOWN;
case FieldDescriptor::TYPE_MESSAGE:
- // TODO: not the final package name
if (field->message_type()->full_name() == "android.os.statsd.AttributionNode") {
return JAVA_TYPE_ATTRIBUTION_CHAIN;
} else if (field->message_type()->full_name() == "android.os.statsd.KeyValuePair") {
@@ -147,7 +146,7 @@ static java_type_t java_type(const FieldDescriptor* field) {
void collate_enums(const EnumDescriptor& enumDescriptor, AtomField* atomField) {
for (int i = 0; i < enumDescriptor.value_count(); i++) {
atomField->enumValues[enumDescriptor.value(i)->number()] =
- enumDescriptor.value(i)->name().c_str();
+ enumDescriptor.value(i)->name();
}
}
@@ -528,7 +527,7 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
vector<java_type_t> signature;
errorCount += collate_atom(atom, atomDecl.get(), &signature);
- if (atomDecl->primaryFields.size() != 0 && atomDecl->exclusiveField == 0) {
+ if (!atomDecl->primaryFields.empty() && atomDecl->exclusiveField == 0) {
print_error(atomField, "Cannot have a primary field without an exclusive field: %s\n",
atomField->name().c_str());
errorCount++;
@@ -541,8 +540,7 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
atomField->name().c_str());
errorCount++;
continue;
- }
- else if ((oneofAtom->name() != ONEOF_PUSHED_ATOM_NAME) &&
+ } else if ((oneofAtom->name() != ONEOF_PUSHED_ATOM_NAME) &&
(oneofAtom->name() != ONEOF_PULLED_ATOM_NAME)) {
print_error(atomField, "Atom is neither a pushed nor pulled atom: %s\n",
atomField->name().c_str());
@@ -578,7 +576,7 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
printf(" ");
for (vector<java_type_t>::const_iterator jt = it->first.begin(); jt != it->first.end();
jt++) {
- printf(" %d", (int)*jt);
+ printf(" %d", static_cast<int>(*jt));
}
printf("\n");
}
@@ -589,7 +587,7 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
printf(" ");
for (vector<java_type_t>::const_iterator jt = it->first.begin(); jt != it->first.end();
jt++) {
- printf(" %d", (int)*jt);
+ printf(" %d", static_cast<int>(*jt));
}
printf("\n");
}
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index e637ed945a08..5d196c4b8290 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -47,8 +47,8 @@ const int FIRST_UID_IN_CHAIN_ID = 0;
*
* `OneofDescriptor::name()` returns the name of the oneof.
*/
-const string ONEOF_PUSHED_ATOM_NAME = "pushed";
-const string ONEOF_PULLED_ATOM_NAME = "pulled";
+const char ONEOF_PUSHED_ATOM_NAME[] = "pushed";
+const char ONEOF_PULLED_ATOM_NAME[] = "pulled";
enum AnnotationId : uint8_t {
ANNOTATION_ID_IS_UID = 1,
@@ -63,7 +63,7 @@ enum AnnotationId : uint8_t {
const int ATOM_ID_FIELD_NUMBER = -1;
-const string DEFAULT_MODULE_NAME = "DEFAULT";
+const char DEFAULT_MODULE_NAME[] = "DEFAULT";
/**
* The types for atom parameters.
@@ -95,9 +95,9 @@ union AnnotationValue {
int intValue;
bool boolValue;
- AnnotationValue(const int value) : intValue(value) {
+ explicit AnnotationValue(const int value) : intValue(value) {
}
- AnnotationValue(const bool value) : boolValue(value) {
+ explicit AnnotationValue(const bool value) : boolValue(value) {
}
};
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
index ffbe9f800736..6fcf267cf39c 100644
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ b/tools/stats_log_api_gen/java_writer.cpp
@@ -42,6 +42,7 @@ static int write_java_q_logger_class(FILE* out, const SignatureInfoMap& signatur
static void write_java_annotation_constants(FILE* out) {
fprintf(out, " // Annotation constants.\n");
+ const map<AnnotationId, string>& ANNOTATION_ID_CONSTANTS = get_annotation_id_constants();
for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) {
fprintf(out, " public static final byte %s = %hhu;\n", name.c_str(), id);
}
@@ -56,6 +57,7 @@ static void write_annotations(FILE* out, int argIndex,
return;
}
const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
+ const map<AnnotationId, string>& ANNOTATION_ID_CONSTANTS = get_annotation_id_constants();
for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
const string atomConstant = make_constant_name(atomDecl->name);
fprintf(out, " if (%s == code) {\n", atomConstant.c_str());
@@ -102,7 +104,7 @@ static void write_method_signature(FILE* out, const vector<java_type_t>& signatu
for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
arg++) {
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
+ for (const auto& chainField : attributionDecl.fields) {
fprintf(out, ", %s[] %s", java_type_name(chainField.javaType),
chainField.name.c_str());
}
@@ -243,13 +245,15 @@ static int write_method_body(FILE* out, const vector<java_type_t>& signature,
return 0;
}
-static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
+static int write_java_pushed_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
const AtomDecl& attributionDecl, const bool supportQ) {
for (auto signatureInfoMapIt = signatureInfoMap.begin();
signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
// Print method signature.
fprintf(out, " public static void write(int code");
- write_method_signature(out, signatureInfoMapIt->first, attributionDecl);
+ const vector<java_type_t>& signature = signatureInfoMapIt->first;
+ const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
+ write_method_signature(out, signature, attributionDecl);
fprintf(out, ") {\n");
// Print method body.
@@ -259,7 +263,7 @@ static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMa
indent = " ";
}
- int ret = write_method_body(out, signatureInfoMapIt->first, signatureInfoMapIt->second,
+ int ret = write_method_body(out, signature, fieldNumberToAtomDeclSet,
attributionDecl, indent);
if (ret != 0) {
return ret;
@@ -274,8 +278,8 @@ static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMa
fprintf(out, " } else {\n");
fprintf(out, " QLogger.write(code");
int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signatureInfoMapIt->first.begin();
- arg != signatureInfoMapIt->first.end(); arg++) {
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
const char* uidName = attributionDecl.fields.front().name.c_str();
const char* tagName = attributionDecl.fields.back().name.c_str();
@@ -299,18 +303,20 @@ static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMa
return 0;
}
-static int write_java_build_stats_event_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
+static int write_java_pulled_methods(FILE* out, const SignatureInfoMap& signatureInfoMap,
const AtomDecl& attributionDecl) {
for (auto signatureInfoMapIt = signatureInfoMap.begin();
signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) {
// Print method signature.
fprintf(out, " public static StatsEvent buildStatsEvent(int code");
- write_method_signature(out, signatureInfoMapIt->first, attributionDecl);
+ const vector<java_type_t>& signature = signatureInfoMapIt->first;
+ const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
+ write_method_signature(out, signature, attributionDecl);
fprintf(out, ") {\n");
// Print method body.
string indent("");
- int ret = write_method_body(out, signatureInfoMapIt->first, signatureInfoMapIt->second,
+ int ret = write_method_body(out, signature, fieldNumberToAtomDeclSet,
attributionDecl, indent);
if (ret != 0) {
return ret;
@@ -357,9 +363,9 @@ int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attribut
// Print write methods.
fprintf(out, " // Write methods\n");
- errors += write_java_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ);
+ errors += write_java_pushed_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ);
errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap);
- errors += write_java_build_stats_event_methods(out, atoms.pulledAtomsSignatureInfoMap,
+ errors += write_java_pulled_methods(out, atoms.pulledAtomsSignatureInfoMap,
attributionDecl);
if (supportWorkSource) {
errors += write_java_work_source_methods(out, atoms.signatureInfoMap);
diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h
index 8b3b50588efc..afd992be6c5e 100644
--- a/tools/stats_log_api_gen/java_writer.h
+++ b/tools/stats_log_api_gen/java_writer.h
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#pragma once
+#ifndef ANDROID_STATS_LOG_API_GEN_JAVA_WRITER_H
+#define ANDROID_STATS_LOG_API_GEN_JAVA_WRITER_H
#include <stdio.h>
#include <string.h>
@@ -28,11 +29,11 @@
namespace android {
namespace stats_log_api_gen {
-using namespace std;
-
int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
const string& javaClass, const string& javaPackage, const bool supportQ,
const bool supportWorkSource);
} // namespace stats_log_api_gen
} // namespace android
+
+#endif // ANDROID_STATS_LOG_API_GEN_JAVA_WRITER_H
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
index d21e2708b724..be7cb4aeb3f8 100644
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ b/tools/stats_log_api_gen/java_writer_q.cpp
@@ -65,7 +65,7 @@ int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfo
for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
arg++) {
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
+ for (const auto& chainField : attributionDecl.fields) {
fprintf(out, ", %s[] %s", java_type_name(chainField.javaType),
chainField.name.c_str());
}
@@ -407,7 +407,7 @@ void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attribut
if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) {
fprintf(out, "%sprivate static void writeAttributionChain(byte[] buff, int pos",
indent.c_str());
- for (auto chainField : attributionDecl.fields) {
+ for (const auto& chainField : attributionDecl.fields) {
fprintf(out, ", %s[] %s", java_type_name(chainField.javaType), chainField.name.c_str());
}
fprintf(out, ") {\n");
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
index c511a8436416..622ef3e37bad 100644
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ b/tools/stats_log_api_gen/java_writer_q.h
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#pragma once
+#ifndef ANDROID_STATS_LOG_API_GEN_JAVA_WRITER_Q_H
+#define ANDROID_STATS_LOG_API_GEN_JAVA_WRITER_Q_H
#include <stdio.h>
#include <string.h>
@@ -28,8 +29,6 @@
namespace android {
namespace stats_log_api_gen {
-using namespace std;
-
void write_java_q_logging_constants(FILE* out, const string& indent);
int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap,
@@ -44,3 +43,5 @@ int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
} // namespace stats_log_api_gen
} // namespace android
+
+#endif // ANDROID_STATS_LOG_API_GEN_JAVA_WRITER_Q_H
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index b888ce904b31..28302493a8e1 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -15,9 +15,6 @@
#include "native_writer.h"
#include "utils.h"
-using namespace google::protobuf;
-using namespace std;
-
namespace android {
namespace stats_log_api_gen {
@@ -145,7 +142,7 @@ static int run(int argc, char const* const* argv) {
index++;
}
- if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0) {
+ if (cppFilename.empty() && headerFilename.empty() && javaFilename.empty()) {
print_usage();
return 1;
}
@@ -175,9 +172,9 @@ static int run(int argc, char const* const* argv) {
&attributionSignature);
// Write the .cpp file
- if (cppFilename.size() != 0) {
+ if (!cppFilename.empty()) {
FILE* out = fopen(cppFilename.c_str(), "w");
- if (out == NULL) {
+ if (out == nullptr) {
fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str());
return 1;
}
@@ -198,9 +195,9 @@ static int run(int argc, char const* const* argv) {
}
// Write the .h file
- if (headerFilename.size() != 0) {
+ if (!headerFilename.empty()) {
FILE* out = fopen(headerFilename.c_str(), "w");
- if (out == NULL) {
+ if (out == nullptr) {
fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str());
return 1;
}
@@ -214,24 +211,24 @@ static int run(int argc, char const* const* argv) {
}
// Write the .java file
- if (javaFilename.size() != 0) {
- if (javaClass.size() == 0) {
+ if (!javaFilename.empty()) {
+ if (javaClass.empty()) {
fprintf(stderr, "Must supply --javaClass if supplying a Java filename");
return 1;
}
- if (javaPackage.size() == 0) {
+ if (javaPackage.empty()) {
fprintf(stderr, "Must supply --javaPackage if supplying a Java filename");
return 1;
}
- if (moduleName.size() == 0) {
+ if (moduleName.empty()) {
fprintf(stderr, "Must supply --module if supplying a Java filename");
return 1;
}
FILE* out = fopen(javaFilename.c_str(), "w");
- if (out == NULL) {
+ if (out == nullptr) {
fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
return 1;
}
diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp
index 21e88b360dcd..b4fb8dd8321b 100644
--- a/tools/stats_log_api_gen/native_writer.cpp
+++ b/tools/stats_log_api_gen/native_writer.cpp
@@ -24,6 +24,7 @@ namespace stats_log_api_gen {
static void write_native_annotation_constants(FILE* out) {
fprintf(out, "// Annotation constants.\n");
+ const map<AnnotationId, string>& ANNOTATION_ID_CONSTANTS = get_annotation_id_constants();
for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) {
fprintf(out, "const uint8_t %s = %hhu;\n", name.c_str(), id);
}
@@ -39,6 +40,7 @@ static void write_annotations(FILE* out, int argIndex,
return;
}
const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second;
+ const map<AnnotationId, string>& ANNOTATION_ID_CONSTANTS = get_annotation_id_constants();
for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) {
const string atomConstant = make_constant_name(atomDecl->name);
fprintf(out, " if (%s == code) {\n", atomConstant.c_str());
@@ -60,8 +62,6 @@ static void write_annotations(FILE* out, int argIndex,
}
break;
case ANNOTATION_TYPE_BOOL:
- // TODO(b/151786433): Write annotation constant name instead of
- // annotation id literal.
fprintf(out, " %saddBoolAnnotation(%s%s, %s);\n", methodPrefix.c_str(),
methodSuffix.c_str(), annotationConstant.c_str(),
annotation->value.boolValue ? "true" : "false");
@@ -145,7 +145,8 @@ static int write_native_stats_write_methods(FILE* out, const SignatureInfoMap& s
vector<java_type_t> signature = signatureInfoMapIt->first;
const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
// Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
+ if (std::find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) !=
+ signature.end()) {
continue;
}
write_native_method_signature(out, "int stats_write(", signature, attributionDecl, " {");
@@ -219,7 +220,8 @@ static void write_native_stats_write_non_chained_methods(FILE* out,
signature_it != signatureInfoMap.end(); signature_it++) {
vector<java_type_t> signature = signature_it->first;
// Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
+ if (std::find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) !=
+ signature.end()) {
continue;
}
@@ -258,7 +260,8 @@ static int write_native_build_stats_event_methods(FILE* out,
vector<java_type_t> signature = signatureInfoMapIt->first;
const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second;
// Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
+ if (std::find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) !=
+ signature.end()) {
continue;
}
write_native_method_signature(out, "void addAStatsEvent(AStatsEventList* pulled_data, ",
@@ -285,7 +288,8 @@ static void write_native_method_header(FILE* out, const string& methodName,
vector<java_type_t> signature = signatureInfoMapIt->first;
// Key value pairs not supported in native.
- if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
+ if (std::find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) !=
+ signature.end()) {
continue;
}
write_native_method_signature(out, methodName, signature, attributionDecl, ";");
diff --git a/tools/stats_log_api_gen/native_writer.h b/tools/stats_log_api_gen/native_writer.h
index 264d4db29fc9..4e42d1fa2809 100644
--- a/tools/stats_log_api_gen/native_writer.h
+++ b/tools/stats_log_api_gen/native_writer.h
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#pragma once
+#ifndef ANDROID_STATS_LOG_API_GEN_NATIVE_WRITER_H
+#define ANDROID_STATS_LOG_API_GEN_NATIVE_WRITER_H
#include <stdio.h>
#include <string.h>
@@ -24,8 +25,6 @@
namespace android {
namespace stats_log_api_gen {
-using namespace std;
-
int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
const string& cppNamespace, const string& importHeader,
const bool supportQ);
@@ -35,3 +34,5 @@ int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attrib
} // namespace stats_log_api_gen
} // namespace android
+
+#endif // ANDROID_STATS_LOG_API_GEN_NATIVE_WRITER_H
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index 5fd728a29c07..6f78921d8f1c 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -24,7 +24,6 @@ namespace android {
namespace stats_log_api_gen {
using std::map;
-using std::set;
using std::vector;
/**
@@ -32,11 +31,11 @@ using std::vector;
*/
static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) {
va_list args;
- vector<java_type_t> v;
+ vector<java_type_t> v(count);
va_start(args, count);
for (int i = 0; i < count; i++) {
- v.push_back((java_type_t)va_arg(args, int));
+ v[i] = static_cast<java_type_t>(va_arg(args, int));
}
va_end(args);
@@ -222,7 +221,7 @@ TEST(CollationTest, FailOnBadBinaryFieldAtom) {
Atoms atoms;
int errorCount =
collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_TRUE(errorCount > 0);
+ EXPECT_GT(errorCount, 0);
}
TEST(CollationTest, PassOnLogFromModuleAtom) {
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
index 4b3734053421..1eaf42acf153 100644
--- a/tools/stats_log_api_gen/utils.cpp
+++ b/tools/stats_log_api_gen/utils.cpp
@@ -16,11 +16,30 @@
#include "utils.h"
-#include "android-base/strings.h"
-
namespace android {
namespace stats_log_api_gen {
+/**
+ * Inlining this method because "android-base/strings.h" is not available on
+ * google3.
+ */
+static vector<string> Split(const string& s, const string& delimiters) {
+ GOOGLE_CHECK_NE(delimiters.size(), 0U);
+
+ vector<string> result;
+
+ size_t base = 0;
+ size_t found;
+ while (true) {
+ found = s.find_first_of(delimiters, base);
+ result.push_back(s.substr(base, found - base));
+ if (found == s.npos) break;
+ base = found + 1;
+ }
+
+ return result;
+}
+
static void build_non_chained_decl_map(const Atoms& atoms,
std::map<int, AtomDeclSet::const_iterator>* decl_map) {
for (AtomDeclSet::const_iterator atomIt = atoms.non_chained_decls.begin();
@@ -29,6 +48,20 @@ static void build_non_chained_decl_map(const Atoms& atoms,
}
}
+const map<AnnotationId, string>& get_annotation_id_constants() {
+ static const map<AnnotationId, string>* ANNOTATION_ID_CONSTANTS =
+ new map<AnnotationId, string>{
+ {ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID"},
+ {ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP"},
+ {ANNOTATION_ID_PRIMARY_FIELD, "ANNOTATION_ID_PRIMARY_FIELD"},
+ {ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, "ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID"},
+ {ANNOTATION_ID_EXCLUSIVE_STATE, "ANNOTATION_ID_EXCLUSIVE_STATE"},
+ {ANNOTATION_ID_TRIGGER_STATE_RESET, "ANNOTATION_ID_TRIGGER_STATE_RESET"},
+ {ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED"}};
+
+ return *ANNOTATION_ID_CONSTANTS;
+}
+
/**
* Turn lower and camel case into upper case with underscores.
*/
@@ -102,15 +135,15 @@ const char* java_type_name(java_type_t type) {
// Writes namespaces for the cpp and header files, returning the number of
// namespaces written.
void write_namespace(FILE* out, const string& cppNamespaces) {
- vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
- for (string cppNamespace : cppNamespaceVec) {
+ vector<string> cppNamespaceVec = Split(cppNamespaces, ",");
+ for (const string& cppNamespace : cppNamespaceVec) {
fprintf(out, "namespace %s {\n", cppNamespace.c_str());
}
}
// Writes namespace closing brackets for cpp and header files.
void write_closing_namespace(FILE* out, const string& cppNamespaces) {
- vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
+ vector<string> cppNamespaceVec = Split(cppNamespaces, ",");
for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) {
fprintf(out, "} // namespace %s\n", it->c_str());
}
@@ -123,7 +156,7 @@ static void write_cpp_usage(FILE* out, const string& method_name, const string&
for (vector<AtomField>::const_iterator field = atom->fields.begin();
field != atom->fields.end(); field++) {
if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
+ for (const auto& chainField : attributionDecl.fields) {
if (chainField.javaType == JAVA_TYPE_STRING) {
fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType),
chainField.name.c_str());
@@ -190,7 +223,7 @@ void write_native_method_signature(FILE* out, const string& signaturePrefix,
for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
arg++) {
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
+ for (const auto& chainField : attributionDecl.fields) {
if (chainField.javaType == JAVA_TYPE_STRING) {
fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType),
chainField.name.c_str());
@@ -222,7 +255,7 @@ void write_native_method_call(FILE* out, const string& methodName,
for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end();
arg++) {
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
+ for (const auto& chainField : attributionDecl.fields) {
if (chainField.javaType == JAVA_TYPE_STRING) {
fprintf(out, ", %s", chainField.name.c_str());
} else {
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
index 42dc90eb79dc..13a7e2d8a54e 100644
--- a/tools/stats_log_api_gen/utils.h
+++ b/tools/stats_log_api_gen/utils.h
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#pragma once
+#ifndef ANDROID_STATS_LOG_API_GEN_UTILS_H
+#define ANDROID_STATS_LOG_API_GEN_UTILS_H
#include <stdio.h>
#include <string.h>
@@ -28,23 +29,14 @@
namespace android {
namespace stats_log_api_gen {
-using namespace std;
-
-const string DEFAULT_CPP_NAMESPACE = "android,util";
-const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
+const char DEFAULT_CPP_NAMESPACE[] = "android,util";
+const char DEFAULT_CPP_HEADER_IMPORT[] = "statslog.h";
const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
const int JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS = 0x04;
-const map<AnnotationId, string> ANNOTATION_ID_CONSTANTS = {
- {ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID"},
- {ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP"},
- {ANNOTATION_ID_PRIMARY_FIELD, "ANNOTATION_ID_PRIMARY_FIELD"},
- {ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, "ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID"},
- {ANNOTATION_ID_EXCLUSIVE_STATE, "ANNOTATION_ID_EXCLUSIVE_STATE"},
- {ANNOTATION_ID_TRIGGER_STATE_RESET, "ANNOTATION_ID_TRIGGER_STATE_RESET"},
- {ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED"}};
+const map<AnnotationId, string>& get_annotation_id_constants();
string make_constant_name(const string& str);
@@ -81,3 +73,5 @@ int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureI
} // namespace stats_log_api_gen
} // namespace android
+
+#endif // ANDROID_STATS_LOG_API_GEN_UTILS_H
diff --git a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java b/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
index 971aa8e05df2..79e95e81396a 100644
--- a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
@@ -267,42 +267,42 @@ public class TlvBufferUtilsTest {
@Test(expected = IllegalArgumentException.class)
public void testTlvItInvalidSizeT1L0() {
- final byte[] dummy = {
+ final byte[] testTlv = {
0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, dummy);
+ final int testLength = 3;
+ TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, testTlv);
}
@Test(expected = IllegalArgumentException.class)
public void testTlvItInvalidSizeTm3L2() {
- final byte[] dummy = {
+ final byte[] testTlv = {
0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, dummy);
+ final int testLength = 3;
+ TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, testTlv);
}
@Test(expected = IllegalArgumentException.class)
public void testTlvItInvalidSizeT1Lm2() {
- final byte[] dummy = {
+ final byte[] testTlv = {
0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, dummy);
+ final int testLength = 3;
+ TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, testTlv);
}
@Test(expected = IllegalArgumentException.class)
public void testTlvItInvalidSizeT1L3() {
- final byte[] dummy = {
+ final byte[] testTlv = {
0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, dummy);
+ final int testLength = 3;
+ TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, testTlv);
}
@Test(expected = IllegalArgumentException.class)
public void testTlvItInvalidSizeT3L1() {
- final byte[] dummy = {
+ final byte[] testTlv = {
0, 1, 2 };
- final int dummyLength = 3;
- TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, dummy);
+ final int testLength = 3;
+ TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, testTlv);
}
/**
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
index f2961db4eb14..b65de6b9789d 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java
@@ -45,7 +45,7 @@ public class WifiAwareAgentNetworkSpecifierTest {
Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
+ nsSet.add(getMockNetworkSpecifier(10 + i));
}
WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
@@ -78,7 +78,7 @@ public class WifiAwareAgentNetworkSpecifierTest {
@Test
public void testEmptyDoesntMatchAnything() {
WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier();
- WifiAwareNetworkSpecifier ns = getDummyNetworkSpecifier(6);
+ WifiAwareNetworkSpecifier ns = getMockNetworkSpecifier(6);
collector.checkThat("No match expected", ns.canBeSatisfiedBy(dut), equalTo(false));
}
@@ -88,9 +88,9 @@ public class WifiAwareAgentNetworkSpecifierTest {
*/
@Test
public void testSingleMatch() {
- WifiAwareNetworkSpecifier nsThis = getDummyNetworkSpecifier(6);
+ WifiAwareNetworkSpecifier nsThis = getMockNetworkSpecifier(6);
WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(nsThis);
- WifiAwareNetworkSpecifier nsOther = getDummyNetworkSpecifier(8);
+ WifiAwareNetworkSpecifier nsOther = getMockNetworkSpecifier(8);
collector.checkThat("Match expected", nsThis.canBeSatisfiedBy(dut), equalTo(true));
collector.checkThat("No match expected", nsOther.canBeSatisfiedBy(dut), equalTo(false));
}
@@ -105,12 +105,12 @@ public class WifiAwareAgentNetworkSpecifierTest {
Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
+ nsSet.add(getMockNetworkSpecifier(10 + i));
}
WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(
nsSet.toArray(new WifiAwareNetworkSpecifier[numNs]));
- WifiAwareNetworkSpecifier nsOther = getDummyNetworkSpecifier(10000);
+ WifiAwareNetworkSpecifier nsOther = getMockNetworkSpecifier(10000);
for (WifiAwareNetworkSpecifier nsThis: nsSet) {
collector.checkThat("Match expected", nsThis.canBeSatisfiedBy(dut), equalTo(true));
@@ -127,13 +127,13 @@ public class WifiAwareAgentNetworkSpecifierTest {
Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
+ nsSet.add(getMockNetworkSpecifier(10 + i));
}
WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
- nsSet.add(getDummyNetworkSpecifier(100 + numNs));
+ nsSet.add(getMockNetworkSpecifier(100 + numNs));
WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
@@ -149,13 +149,13 @@ public class WifiAwareAgentNetworkSpecifierTest {
Set<WifiAwareNetworkSpecifier> nsSet = new HashSet<>();
for (int i = 0; i < numNs; ++i) {
- nsSet.add(getDummyNetworkSpecifier(10 + i));
+ nsSet.add(getMockNetworkSpecifier(10 + i));
}
WifiAwareAgentNetworkSpecifier newNs = new WifiAwareAgentNetworkSpecifier(
nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
- nsSet.add(getDummyNetworkSpecifier(100 + numNs));
+ nsSet.add(getMockNetworkSpecifier(100 + numNs));
WifiAwareAgentNetworkSpecifier oldNs = new WifiAwareAgentNetworkSpecifier(
nsSet.toArray(new WifiAwareNetworkSpecifier[nsSet.size()]));
@@ -165,10 +165,10 @@ public class WifiAwareAgentNetworkSpecifierTest {
// utilities
/**
- * Returns a WifiAwareNetworkSpecifier with dummy (but valid) entries. Each can be
+ * Returns a WifiAwareNetworkSpecifier with mock (but valid) entries. Each can be
* differentiated (made unique) by specifying a different client ID.
*/
- WifiAwareNetworkSpecifier getDummyNetworkSpecifier(int clientId) {
+ WifiAwareNetworkSpecifier getMockNetworkSpecifier(int clientId) {
return new WifiAwareNetworkSpecifier(WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, clientId, 0, 0, new byte[6],
null, null, 10, 5);
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index c5f98045082b..43d728bf593e 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -1585,7 +1585,7 @@ public class WifiAwareManagerTest {
public void testWifiAwareNetworkCapabilitiesParcel() throws UnknownHostException {
final Inet6Address inet6 = MacAddress.fromString(
"11:22:33:44:55:66").getLinkLocalIpv6FromEui48Mac();
- // note: dummy scope = 5
+ // note: placeholder scope = 5
final Inet6Address inet6Scoped = Inet6Address.getByAddress(null, inet6.getAddress(), 5);
final int port = 5;
final int transportProtocol = 6;